Skip to content

seo: URL-driven list filters and per-page meta descriptions#64

Open
FenjuFu wants to merge 2 commits into
mainfrom
seo-url-driven-filters
Open

seo: URL-driven list filters and per-page meta descriptions#64
FenjuFu wants to merge 2 commits into
mainfrom
seo-url-driven-filters

Conversation

@FenjuFu

@FenjuFu FenjuFu commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Motivation

The projects and events list pages rendered their full dataset once and then filtered it in the browser with an inline display: none script. That works for a human clicking around, but it costs us on SEO:

  • Filter state lived only in JS variables, so a filtered view (agent-skills projects, hackathon events) had no URL — it could not be linked, shared, or indexed.
  • Several pages emitted no <meta name="description"> of their own and fell back to the site-wide default, so search results showed the same generic snippet for /projects, /events, /adopters, /landscape, /contribute, the policy pages and the blog list pages.
  • /events was prerendered at build time, which froze each event's upcoming / ongoing / past badge to whatever the date was when the site was built.

What changed

URL-driven list filters

/projects — category and language filters are now server-rendered links that carry state in the query string (/projects?category=agent-skills&language=TypeScript). Filtering happens on the server; the client-side filter script is gone. Unknown parameter values fall back to all, and an empty result set renders an explicit empty state with a "clear filters" link instead of a blank grid.

/events — same treatment with ?type=meetup / ?type=hackathon etc., and the page switches to prerender = false so each event's status badge is computed at request time rather than at build time.

Canonical URLs already strip the query string (getCanonical uses Astro.url.pathname), so filtered views canonicalize back to the base list page and introduce no duplicate content — they are crawlable and shareable without competing with the canonical page in the index.

Per-page meta descriptions

Added distinct, bilingual descriptions to every page that previously inherited the site-wide default:

Page Before After
/projects, /events, /adopters, /landscape, /contribute site default page-specific
/cla, /values, /security site default page-specific
/blog, /category/<slug>, /tag/<slug> site default page/category/tag-specific

MarkdownLayout now forwards a description from its frontmatter into the page metadata, which is what makes the three policy pages possible.

Verification

  • astro check — 103 files, 0 errors / 0 warnings / 0 hints
  • eslint and prettier clean on the touched files
  • Verified against the dev server:
    • /projects?category=agent-skills&language=TypeScript server-renders exactly the intersection (1 card), both chips show active, and no filter script remains in the HTML
    • /events?type=hackathon renders only hackathons with the right chip active
    • <meta name="description"> is page-specific on /projects, /events and /security
    • <link rel="canonical"> on a filtered /projects URL still points at https://opensource.iflytek.com/projects

Notes

No visual redesign — the filter chips keep their existing styling and active/inactive states; they are <a> elements instead of <button> elements. Filtering now costs a navigation instead of an instant DOM toggle, which is the intended trade for having real URLs.

Make filtered views of the projects and events pages crawlable and
shareable by moving filter state into URL query parameters:

- /projects: category/language filters are now server-rendered links
  (?category=...&language=...) filtered on the server, replacing the
  client-side JS show/hide script; add an empty-state with a clear link
- /events: switch to server rendering with ?type=... filter links,
  replacing the client-side filter script; event status (upcoming/
  ongoing/past) is now computed at request time instead of being frozen
  at build time

Canonical URLs already strip query strings, so filtered views
canonicalize to the base list page and add no duplicate content.

Also add unique meta descriptions to pages that previously fell back to
the site-wide default: projects, events, adopters, landscape,
contribute, CLA, values, security and the blog list/category/tag pages
(MarkdownLayout now passes description through).

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment Jul 24, 2026 3:31am

@dongjiang1989 dongjiang1989 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @FenjuFu
Great feature.

Need add Changelog to CHANGELOG.md

@FenjuFu

FenjuFu commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@dongjiang1989 Thanks for the review. Added the SEO and URL-driven filtering changes to the CHANGELOG.md Unreleased section in commit 8570bb1.

@dongjiang1989

Copy link
Copy Markdown
Contributor

Please fix CI fail. DCO setting

@dongjiang1989 dongjiang1989 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check all added English and Chinese descriptions

Comment thread src/pages/cla.astro
frontmatter={{
title: '贡献者许可协议',
titleEn: 'Contributor License Agreement',
description:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add en description?

@FenjuFu

FenjuFu commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @dongjiang1989! Added the changelog entry under [Unreleased] → Changed in CHANGELOG.md (commit 8570bb1), already pushed to this branch. Ready for another look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants