Community Page
v1.0.0Added in 1.8.0
A community hub: a drawn live chat hero, member stats, forum highlights, a dot map of local chapters, ambassadors and member builds.
The hero rises in once beside a drawn #show-and-tell chat: messages with a timeline attachment and reactions, a typing indicator, member avatars with presence dots floating on two orbits, and (on wider screens) a meetup card, a Solved thread and a welcome chip drifting around it. The online count and the 🎉 reactions tick up every few seconds while the hero is on screen, and the Members stat ticks with them. The stats count up the first time they scroll in. In the forum, Trending, New and Unanswered tabs (arrow keys move between them) switch the thread list; every thread is one link with its category dot, author, relative time, Solved, Planned or No replies yet badge, participants and reply and like counts. The chapters map is a dot grid of the continents with a pin per chapter: click a pin (or hover or focus a chapter card) to show the chapter's leaders, members and next meetup in the callout. The region chips (a scrollable row on phones) filter the chapter cards and dim the other pins; Show more reveals the rest of the cards. Join on a chapter toggles to Joined (aria-pressed) and counts you in. The ambassador form checks name, email (on blur too), city and a 30-character minimum for the idea, shows each error under its field and focuses the first; while onApply runs the button spins, a rejection shows an error, then a success panel thanks the applicant by first name with the next steps. Member builds are cards with drawn previews, each one link, next to a champions leaderboard with medals and rank changes. The closing band takes a newsletter signup. Reduced motion keeps everything still.
Built with
The sections this page is made of. In the full-screen preview, hold Alt to outline each one on the page.
Add to a project
npx wingo-ui@latest add community-pagePro item: the CLI needs a Pro account. See plans
Usage
// app/(marketing)/community/page.tsx
"use client"
import Link from "next/link"
import { CommunityPage } from "@/components/templates/community-page"
export default function CommunityRoute() {
return (
<CommunityPage
linkComponent={Link}
ctaTone="brand"
onApply={async (values) => {
const response = await fetch("/api/community/ambassadors", { method: "POST", body: JSON.stringify(values) })
if (!response.ok) throw new Error("Could not send the application")
}}
onJoinChapter={(chapter, joined) => {
void fetch(`/api/community/chapters/${chapter.id}`, { method: joined ? "POST" : "DELETE" })
}}
/>
)
}Props
designdefault"classic""classic" | "bold" | "minimal"The whole page's look. classic: a split hero over a dotted glow, a divided stats row, gray bands and a split newsletter band; bold: a pill header, a giant stage title on a gradient mesh, an inverted stats band, rounder cards, a drawn newsletter band and a wordmark footer; minimal: a transparent header, a centered stacked hero without floating cards, outlined flat cards, no gray bands, a plain closing band and a simple footer. statsProps and ctaProps still win.
statsdefault"COMMUNITY_STATS"StatsSectionItem[]The stats row under the hero: { value, label, description?, prefix?, suffix?, decimals? }. With live, the first one ticks.
forumCategoriesdefault"COMMUNITY_FORUM_CATEGORIES"CommunityForumCategory[]{ value, label, color, threads, href }: the dot color and label on each thread and the side list.
threadsdefault"COMMUNITY_THREADS"CommunityThread[]{ id, title, excerpt, category, author, postedAt, replies, likes, participants, status?, href }. Trending ranks threads with replies by likes and replies, New sorts by date, Unanswered keeps the ones with no replies.
regionsdefault"COMMUNITY_REGIONS"CommunityRegion[]The chapter filter chips, { value, label }; only regions with chapters show.
chaptersdefault"COMMUNITY_CHAPTERS"CommunityChapter[]{ id, city, country, region, lat, lon, members, leaders, timeZone, nextMeetup?, isNew?, href }. lat and lon place the pin; the meetup shows in the chapter's time zone.
ambassadorsdefault"COMMUNITY_AMBASSADORS"CommunityAmbassador[]Featured ambassadors: { id, name, city, specialty, meetups, since }.
perksdefault"COMMUNITY_PERKS"CommunityPerk[]What ambassadors get: { id, icon?, title, description }.
showcasedefault"COMMUNITY_SHOWCASE"CommunityShowcaseItem[]Member builds: { id, kind, title, description, author, uses, likes, preview, previewItems?, href }. preview picks the drawn mini scene: board, okr, calendar, flow or sync.
championsdefault"COMMUNITY_CHAMPIONS"LeaderboardItem[]Champions of the month for the Leaderboard: { id, name, value (points), description?, previousRank? }.
principlesdefault"COMMUNITY_PRINCIPLES"CommunityPrinciple[]The code of conduct summary: { id, icon?, title, description }.
labelsdefault"DEFAULT_COMMUNITY_PAGE_LABELS"Partial<CommunityPageLabels>Every visible string; the ones with numbers or names in them are functions.
hrefsdefault"DEFAULT_COMMUNITY_PAGE_HREFS"Partial<CommunityPageHrefs>{ forum, discord, ask, chapters, events, templates, conduct, report, privacy, announcement, pill }.
nowdefault"2026-10-12T15:00:00Z"stringThe ISO moment thread times count from ("5 hr. ago"), fixed so the server and the browser agree; an invalid value shows plain dates.
onlinedefault1284numberMembers online in the hero before the live ticks.
livedefaulttruebooleanThe online count, the 🎉 reactions and the first stat tick up every few seconds while the hero is on screen.
defaultTabdefault"trending""trending" | "new" | "unanswered"The forum tab on load.
threadLimitdefault5numberThreads per forum tab.
defaultRegiondefault"all"stringThe chapter filter on load: all or a region value.
chapterLimitdefault6numberChapter cards before the Show more button; 0 shows every chapter.
defaultJoinedstring[]Chapter ids the visitor already joined.
minIdeadefault30numberThe shortest What would you organize? answer, in characters. 0 drops the rule.
ctaVariantdefault"split""split" | "inverted" | "soft"The newsletter band: copy beside the form on a raised panel, a solid band or a gray band. Applies to the classic design.
showAnnouncementdefaulttruebooleanThe Summit strip above the header bar.
showStatsdefaulttruebooleanThe stats row under the hero.
showForumdefaulttruebooleanForum highlights.
showChaptersdefaulttruebooleanThe chapters map and list.
showAmbassadorsdefaulttruebooleanThe ambassadors program and its form.
showShowcasedefaulttruebooleanMember builds and the champions leaderboard.
showConductdefaulttruebooleanThe code of conduct summary.
showCtadefaulttruebooleanThe newsletter band.
alternatedefaulttruebooleanGray bands on every other section. Applies to the classic and bold designs.
tonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"Accents: the hero glow and pill tag, the active reaction, map pins, perk icons, the Ambassador badge and leaderboard bars.
ctaTonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"Join the forum, Ask the community, Send application, the header's Get started and the newsletter button; brand is the marketing orange.
radiusdefault"md""none" | "sm" | "md" | "lg" | "full"The corners of the form fields.
headerdefaulttruebooleanThe marketing header; off inside a site layout.
footerdefaulttruebooleanThe marketing footer.
headerPropsPartial<MarketingHeaderProps>Passed to MarketingHeader.
footerPropsPartial<MarketingFooterProps>Passed to MarketingFooter.
statsPropsPartial<StatsSectionProps>Overrides for the StatsSection.
ctaPropsPartial<CtaSectionProps>Overrides for the CtaSection.
onApply(values: CommunityApplication) => (void | Promise<unknown>)The ambassador application: { name, email, city, idea }. A promise keeps the button loading and a rejection shows an error. Without it the form waits 900 ms and shows the success panel.
onJoinChapter(chapter: CommunityChapter, joined: boolean) => voidA chapter was joined or left.
onSubscribe(email: string) => (void | Promise<unknown>)The newsletter band; a rejected promise shows an error. Without it: 900 ms, then success.
animateIndefaulttruebooleanThe hero rises in, the scene floats, the counts tick and the stats count up; false keeps the page still (thumbnails). Reduced motion always does.
localedefault"en-US"stringIntl locale for counts, relative thread times and meetup dates.
linkComponentdefault"<a>"(props: LinkComponentProps) => ReactNodeThe router link for every link on the page (next/link in an app).
classNamestringClasses for the root.
classNamesPartial<Record<CommunityPageSlot, string>>Classes for header, hero, title, scene, stats, forum, thread, chapters, map, chapter, ambassadors, ambassador, form, success, showcase, build, champions, conduct, cta and footer.
Parts
COMMUNITY_PAGE_SAMPLE
constantAll the sample content in one object: now, stats, forum categories, threads, regions, chapters, ambassadors, perks, showcase, champions and principles.
COMMUNITY_NOW
constantThe fixed moment the sample thread times count from: 2026-10-12T15:00:00Z.
COMMUNITY_STATS
constant48,213 members, 3,420 posts this week, 112 countries and 64 chapters.
COMMUNITY_FORUM_CATEGORIES
constantShow and tell, Templates, Automations, Integrations and API, Help and how-to, Feedback and ideas.
COMMUNITY_THREADS
constantTen forum threads, three of them still unanswered.
COMMUNITY_REGIONS
constantAmericas, Europe, Africa and Asia Pacific.
COMMUNITY_CHAPTERS
constantTwelve chapters from New York to Sydney, each with leaders and the next meetup.
COMMUNITY_AMBASSADORS
constantFour featured ambassadors.
COMMUNITY_PERKS
constantSix ambassador perks: plan, meetup budget, Summit, early access, the team, swag.
COMMUNITY_SHOWCASE
constantSix member builds: templates, automations and an integration.
COMMUNITY_CHAMPIONS
constantThe five champions of the month with points and last month's rank.
COMMUNITY_PRINCIPLES
constantThe four code of conduct principles.
DEFAULT_COMMUNITY_PAGE_LABELS
constantThe English strings.
DEFAULT_COMMUNITY_PAGE_HREFS
constantThe default link targets.
COMMUNITY_PAGE_DESIGNS
constantThe design names, classic first: ["classic", "bold", "minimal"].
CommunityPageProps
typeProps of CommunityPage.
CommunityPageDesign
type"classic" | "bold" | "minimal".
CommunityThread
typeOne forum thread.
CommunityForumCategory
typeOne forum category with its dot color.
CommunityForumTab
type"trending" | "new" | "unanswered".
CommunityChapter
typeOne local chapter with its map position and next meetup.
CommunityMeetup
typeA chapter's next meetup: { title, startsAt, venue, going }.
CommunityRegion
typeA chapter region: { value, label }.
CommunityAmbassador
typeOne featured ambassador.
CommunityPerk
typeOne ambassador perk.
CommunityShowcaseItem
typeOne member build.
CommunityPrinciple
typeOne code of conduct principle.
CommunityApplication
typeThe ambassador form's values passed to onApply.
CommunityPageLabels
typeThe strings labels can override.
CommunityPageHrefs
typeThe link targets hrefs can override.
Examples
Bold design
design="bold": a giant stage title on a gradient mesh, an inverted stats band, rounder cards and a wordmark footer.
Minimal design
design="minimal": a transparent header, a centered quiet hero, outlined flat cards, no gray bands and a simple footer.
Brand orange, Europe first
tone and ctaTone brand, the chapters filtered to Europe and London already joined.
Unanswered threads, inverted band
The forum opens on Unanswered so members see where help is needed; the newsletter sits on a solid band.
Application queue down
An onApply that rejects: fill the ambassador form and send it to see the error while every value stays.
Dependencies
Files
- components/templates/community-page.tsx
- components/templates/community-page-data.ts