From ee1eab77c6be8768cfdade335162cdc5aa1e88c2 Mon Sep 17 00:00:00 2001 From: koki Date: Wed, 27 May 2026 19:33:45 +0800 Subject: [PATCH] feat(landing): add Community link + first-party Ambassadors page (#3066) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(landing): add Community link to top nav Adds a 'Community' entry to the landing-page nav between Blog and the Star CTA, linking to /community/ which Cloudflare Pages 302-redirects to the contributors honor-cards page (currently a Vercel deploy). Translations added for all 18 locales. The nav slot was previously empty after Blog because Contact had been intentionally pulled from the bar (left as a footer + #contact anchor). * fix(landing): use literal /community/ href so non-default locales don't 404 PerishCode review caught that href('/community/') routes through localizedHref and produces /zh/community/, /ja/community/, etc. The _redirects rule only matches the literal /community/ and the [locale]/[...path].astro catch-all does not generate community pages, so 17 of the 18 translated locales would have hit a Cloudflare 404. The destination is a single non-locale-aware external page, so skip the locale prefix entirely — same shape as the GitHub Star and Download CTAs. * feat(landing): host community + ambassadors page first-party Lands the contributors / ambassadors page as a static asset at apps/landing-page/public/community/index.html, served at /community/ on open-design.ai. Drops the temporary 302 to the Vercel preview URL (d5458c46-…vercel.app) — that hostname was a deploy-time UUID Vercel could recycle, which the reviewer correctly flagged as a follow-up. The page now opens with an Ambassadors section: vocation, patronage, covenant — three columns of the program in Renaissance-atelier voice, with a single Apply on Discord CTA pointing at the ambassador channel (discord.gg/2p7Ajbxw3h). Maintainers / leaderboards / good-first-issues sit below as before. Header.tsx comment updated to point at the new source of truth instead of the deleted redirect rule. * fix(community): drop time-bound claims, tighten bot heuristic, drop dead CORE_TEAM entry PerishCode review on ff1cd44b flagged three correctness issues with the static community page. Addressing each: * The 'This week's signal' / 'This week's leader' / 'Last 7 days' / 'PRs · 7d' framing made promises a frozen RANKING_SNAPSHOT can't keep — three weeks from build, the page would be calling the 2026-05-26 leaderboard 'this week's leader.' Renamed to time-neutral copy ('Recent signal', 'A recent leader', 'Snapshot', 'Recent PRs') and dropped the snapshot's 'since' field so we don't pin a window we can't honour. Real refresh pipeline is a follow-up. * 'Showing first N · resets every 30 minutes' didn't describe the code (no caching of any kind exists; each page load re-hits /search/issues and /users/:login). Replaced with a truthful 'Showing first N open good-first-issues.' * The bot exclusion heuristic used substring match on bot/cursor/agent, which would silently drop real logins like 'agentina', 'cursorsmith', 'robothai'. Tightened to a whole-token regex (/(?:^|[-_])(bot|cursor| agent)(?:$|[-_])/) and dropped 'leon wang' from CORE_TEAM — it had an embedded space, which GitHub logins never do, so the entry was unreachable dead code. --------- Co-authored-by: koki yanlai xu --- apps/landing-page/app/_components/header.tsx | 20 +- apps/landing-page/app/i18n.ts | 20 + apps/landing-page/public/community/index.html | 876 ++++++++++++++++++ 3 files changed, 915 insertions(+), 1 deletion(-) create mode 100644 apps/landing-page/public/community/index.html diff --git a/apps/landing-page/app/_components/header.tsx b/apps/landing-page/app/_components/header.tsx index f2fa3e5f6..bcb3e9789 100644 --- a/apps/landing-page/app/_components/header.tsx +++ b/apps/landing-page/app/_components/header.tsx @@ -45,7 +45,8 @@ export interface HeaderProps { | 'templates' | 'craft' | 'blog' - | 'tutorials'; + | 'tutorials' + | 'community'; /** * Live counts from the Markdown catalogs. Required so we can never * silently render stale fallback numbers when a caller forgets to @@ -247,6 +248,23 @@ export function Header({ {headerCopy.nav.blog} + {/* + Community is a static contributors / ambassadors page served + from `apps/landing-page/public/community/index.html` — Astro + copies `public/` verbatim, so this hits Cloudflare Pages as a + first-party route at `/community/`. + + The href is the literal `/community/` rather than + `href('/community/')` because the page is a single non- + locale-aware destination — locale-prefixed variants like + `/zh/community/` would fall through to a 404 since the + `[locale]/[...path].astro` catch-all does not generate it. + */} +
  • + + {headerCopy.nav.community} + +
  • {/* Contact intentionally NOT exposed in the top nav: it's a page-internal anchor (`#contact` on the homepage CTA section) diff --git a/apps/landing-page/app/i18n.ts b/apps/landing-page/app/i18n.ts index f9f3c26e8..6451cfe2e 100644 --- a/apps/landing-page/app/i18n.ts +++ b/apps/landing-page/app/i18n.ts @@ -173,6 +173,8 @@ export interface HeaderCopy { /** Standalone link to the YouTube tutorials channel. */ tutorials: string; blog: string; + /** External community / contributors page (currently a Vercel deploy). */ + community: string; contact: string; }; download: string; @@ -965,6 +967,7 @@ const COMMON_COPY: Record = { craft: 'Craft', tutorials: 'Tutorials', blog: 'Blog', + community: 'Community', contact: 'Contact', }, download: 'Download', @@ -997,6 +1000,7 @@ const COMMON_COPY: Record = { craft: '工艺', tutorials: '教程', blog: '博客', + community: '社区', contact: '联系', }, download: '下载', @@ -1029,6 +1033,7 @@ const COMMON_COPY: Record = { craft: '工藝', tutorials: '教程', blog: '部落格', + community: '社群', contact: '聯絡', }, download: '下載', @@ -1061,6 +1066,7 @@ const COMMON_COPY: Record = { craft: 'クラフト', tutorials: 'チュートリアル', blog: 'ブログ', + community: 'コミュニティ', contact: '連絡', }, download: 'ダウンロード', @@ -1093,6 +1099,7 @@ const COMMON_COPY: Record = { craft: '크래프트', tutorials: '튜토리얼', blog: '블로그', + community: '커뮤니티', contact: '문의', }, download: '다운로드', @@ -1125,6 +1132,7 @@ const COMMON_COPY: Record = { craft: 'Gestaltung', tutorials: 'Tutorials', blog: 'Blog', + community: 'Community', contact: 'Kontakt', }, download: 'Download', @@ -1157,6 +1165,7 @@ const COMMON_COPY: Record = { craft: 'Conception', tutorials: 'Tutoriels', blog: 'Blog', + community: 'Communauté', contact: 'Contact', }, download: 'Télécharger', @@ -1189,6 +1198,7 @@ const COMMON_COPY: Record = { craft: 'Правила', tutorials: 'Уроки', blog: 'Блог', + community: 'Сообщество', contact: 'Контакт', }, download: 'Скачать', @@ -1221,6 +1231,7 @@ const COMMON_COPY: Record = { craft: 'Oficio', tutorials: 'Tutoriales', blog: 'Blog', + community: 'Comunidad', contact: 'Contacto', }, download: 'Descargar', @@ -1253,6 +1264,7 @@ const COMMON_COPY: Record = { craft: 'Ofício', tutorials: 'Tutoriais', blog: 'Blog', + community: 'Comunidade', contact: 'Contato', }, download: 'Baixar', @@ -1285,6 +1297,7 @@ const COMMON_COPY: Record = { craft: 'Regole', tutorials: 'Tutorial', blog: 'Blog', + community: 'Comunità', contact: 'Contatto', }, download: 'Scarica', @@ -1317,6 +1330,7 @@ const COMMON_COPY: Record = { craft: 'Quy tắc', tutorials: 'Hướng dẫn', blog: 'Blog', + community: 'Cộng đồng', contact: 'Liên hệ', }, download: 'Tải xuống', @@ -1349,6 +1363,7 @@ const COMMON_COPY: Record = { craft: 'Reguły', tutorials: 'Samouczki', blog: 'Blog', + community: 'Społeczność', contact: 'Kontakt', }, download: 'Pobierz', @@ -1381,6 +1396,7 @@ const COMMON_COPY: Record = { craft: 'Aturan', tutorials: 'Tutorial', blog: 'Blog', + community: 'Komunitas', contact: 'Kontak', }, download: 'Unduh', @@ -1413,6 +1429,7 @@ const COMMON_COPY: Record = { craft: 'Regels', tutorials: 'Tutorials', blog: 'Blog', + community: 'Community', contact: 'Contact', }, download: 'Download', @@ -1445,6 +1462,7 @@ const COMMON_COPY: Record = { craft: 'حرفة', tutorials: 'الدروس', blog: 'المدونة', + community: 'المجتمع', contact: 'تواصل', }, download: 'تنزيل', @@ -1477,6 +1495,7 @@ const COMMON_COPY: Record = { craft: 'Kurallar', tutorials: 'Eğitimler', blog: 'Blog', + community: 'Topluluk', contact: 'İletişim', }, download: 'İndir', @@ -1509,6 +1528,7 @@ const COMMON_COPY: Record = { craft: 'Правила', tutorials: 'Туторіали', blog: 'Блог', + community: 'Спільнота', contact: 'Контакт', }, download: 'Завантажити', diff --git a/apps/landing-page/public/community/index.html b/apps/landing-page/public/community/index.html new file mode 100644 index 000000000..a9cc0ebe4 --- /dev/null +++ b/apps/landing-page/public/community/index.html @@ -0,0 +1,876 @@ + + + + + + +Contributors — Open Design + + + + + + + + + + +
    +
    +
    +
    + Contributors · 2026 cycle +

    Open design takes shape
    when you ship it.

    +

    Open Design is built by people, in public. Skills, DESIGN.md systems, plugins, docs — every commit is a brushstroke. Pick an issue, send a PR, and earn a one-of-one honor card the moment you're merged.

    + +
    +
    + Honor card · Giotto tier +
    + Open Design contributor honor card — @dev-kp-eloper, top 99.9%, Giotto tier +
    +
    + Auto-minted on first merge + PNG · shared on X +
    +
    +
    +
    + +
    +
    +
    +
    + Open Design Ambassadors +

    Be Open Design's voice in your city.

    +

    Open a local atelier. Convene the meetups, the demos, the late-night critiques — the studio carries the work with budget, materials, and a line straight to the team.

    +
    +
    + + + Apply on Discord + + +

    Ambassadors turn Open Design from a repository into something contributors can meet — in a room, with ink on the table and coffee gone cold.

    +
    +
    + +
    +
    +
    I · Vocation
    +

    Painters of the local scene.

    +

    Designers, developers, organizers — the kind who already gather others. We give the gathering a flag.

    +
      +
    • ·Local Atelier Host — you keep a recurring meetup, study group, or late-night hack alive.
    • +
    • ·Online community lead — Discord, WeChat, Telegram, X spaces.
    • +
    • ·Practising contributor or evangelist — already shipping work, posting craft, ushering newcomers.
    • +
    • ·Comfortable carrying the name — bound to the Code of Conduct, mindful of the brand.
    • +
    +
    + +
    +
    II · Patronage
    +

    What the atelier extends.

    +

    Not a volunteer badge. A working bond — with budget, standing, and access.

    +
      +
    • ·A page on the site — portrait, city, biography, socials, the chronicle of your events.
    • +
    • ·First sight — beta features, internal roadmap previews, releases ahead of the queue.
    • +
    • ·The atelier kit — posters, slide decks, demo pieces, swag; a purse for venue, drinks, and photography.
    • +
    • ·A line to the studio — private channel, monthly sync, a dedicated path for your feedback.
    • +
    • ·A way forward — honor cards and tiers, with a path into regional lead, speaker, or paid community roles.
    • +
    +
    + +
    +
    III · Covenant
    +

    The discipline of the studio.

    +

    A modest commitment, but binding. Extended absence folds into alumni status — the circle stays small and serious.

    +
      +
    • ·Convene at least one event per month or quarter — local or online.
    • +
    • ·Welcome the new hand — usher newcomers through their first contribution.
    • +
    • ·Listen close — gather honest feedback from users, designers, developers, teams.
    • +
    • ·Leave a record — publish a recap after every gathering: attendance, photographs, links, leads.
    • +
    • ·Carry the name well — hold to the Code of Conduct; no misuse of the mark, no deals signed on the studio's behalf.
    • +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    + Steering the ship +

    The maintainers.

    +
    +

    Maintainers protect the direction and quality of Open Design: they review contributions, keep the standard coherent, and make room for more contributors to earn their place in the project.

    +
    + +
    +
    +
    +
    +
    Nagendhra-web
    +
    Maintainer
    +
    +

    Nagendhra brings a data engineer's instinct for production truth: find the failure, measure the edge case, and fix it properly. In Open Design, that shows up in deploy preflight work, asset-bundling hardening, and Windows fixes that make the project feel trustworthy when contributors ship.

    + +
    + +
    +
    +
    +
    Sid-Qin
    +
    Maintainer
    +
    +

    Sid is the generalist engineer with a designer's eye for detail: the kind of maintainer who notices both the broken CLI path and the crooked interaction affordance. In Open Design, Sid keeps export flows, plugin actions, Windows shims, MIME handling, and agent plumbing sharp enough for a community to build on.

    + +
    +
    +
    +
    + +
    +
    +
    +
    + All-time signal +

    The contributors with deep roots.

    +
    +

    A long-running record of talented contributors who keep turning ideas, fixes, and craft into the shared Open Design standard.

    +
    + +
    +
    +
    +
    01 All-time contributor
    +
    Repository history
    +
    +
    +
    +
    +
    +

    The long tail matters: design systems, docs fixes, examples, and small repairs are how an open design language becomes dependable.

    +
    +
    +
    Commits
    +
    #01
    External rank
    +
    +
    + +
    +
    + # + Contributor + Commits + Rank + +
    +
    +
    02
    +
    03
    +
    04
    +
    05
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + Recent signal +

    Ten contributors with recent momentum.

    +
    +

    A snapshot of sharp contributors landing PRs, improving the product, and making Open Design feel alive.

    +
    + +
    + +
    +
    +
    01 A recent leader
    +
    Snapshot
    +
    +
    +
    +
    +
    +

    A contributor taking the lead with focused, generous work.

    +

    +
    +
    +
    #01
    Rank
    +
    Recent PRs
    +
    +
    + +
    +
    + # + Contributor + PRs + Rank + +
    +
    +
    02
    +
    03
    +
    04
    +
    05
    +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    + Pick your first contribution +

    Open issues, tagged for you.

    +
    +

    Live from label:“good first issue” on the Open Design repo. Comment on an issue to claim it — a maintainer will assign it within a day.

    +
    + +
    +
    + +
    good first issue
    + + +
    +
    + +
    good first issue
    + + +
    +
    + +
    good first issue
    + + +
    +
    + +
    + Showing first open good-first-issues + See all on GitHub → +
    +
    +
    + + +
    +
    +
    +
    + Four steps · any skill level +

    From zero to merged, in an afternoon.

    +
    +

    Whether you're a designer, a writer, an engineer, or someone who just spotted a typo — there's a contribution shape for you. Here's the path.

    +
    + +
    +
    +
    +
    Step 01
    +

    Find a spark.

    +

    Browse the good-first-issues list above, or open a new issue describing something you'd improve. Designers — DESIGN.md systems are the easiest entry.

    +
    +
    +
    +
    Step 02
    +

    Open a draft PR.

    +

    Fork, branch, push. Mark it draft — it signals you want feedback early. Mention which issue it closes. The CI is fast; bot-cards stays on its own branch.

    +
    +
    +
    +
    Step 03
    +

    Review with a human.

    +

    A maintainer reviews within 24h. We're kind, specific, and never gatekeep. If you're stuck, drop the PR link in Discord #help.

    +
    +
    +
    +
    Step 04
    +

    Merge → card.

    +

    The bot mints your honor card the moment you're merged and pushes it to the bot-cards branch. Share it on X with #openDesign — we repost the best ones.

    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + Where contributors hang out +

    Talk to the people who'll review your PR.

    +

    Our Discord is where contributors show shipped work, discuss plugins, join beta tests, and get help when a PR gets stuck. No fake activity counters — just the channels people can actually use.

    + +
    +
    +
    Community Discord
    +
    +
    #showcasework shipped
    +
    #pluginbuilders
    +
    #beta-testearly feedback
    +
    #helpunstuck
    +
    +
    +
    +
    +
    + + + + + + + +