Repository navigation
feat(SEO/i18n): add alternate links for multilingual pages - #3524
Conversation
There was a problem hiding this comment.
Pull request overview
Adds automatic rel="alternate"/hreflang link generation for multilingual routes during production rendering, ensuring URLs respect base, siteOrigin, and route.cleanUrls, and documents/tests the behavior across unit + e2e fixtures.
Changes:
- Generate per-route alternate-language link sets from the route list and inject them into the rendered HTML
<head>. - Thread alternate-link data through SSG (including CSR fallbacks) and the experimental SSG worker.
- Add unit + production e2e coverage, and document multilingual SEO behavior in EN/ZH guides.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| website/docs/zh/guide/basic/i18n.mdx | Documents multilingual SEO alternate link generation (ZH). |
| website/docs/zh/guide/advanced/custom-head.mdx | Adds alternate-link tag to the auto-injected head tag list (ZH). |
| website/docs/en/guide/basic/i18n.mdx | Documents multilingual SEO alternate link generation (EN). |
| website/docs/en/guide/advanced/custom-head.mdx | Adds alternate-link tag to the auto-injected head tag list (EN). |
| packages/core/src/node/ssg/renderPageWorker.ts | Passes per-route alternate links into worker rendering. |
| packages/core/src/node/ssg/renderPages.ts | Computes alternate links once and wires them through SSG/CSR/worker paths. |
| packages/core/src/node/ssg/renderPage.ts | Extends renderPage to accept alternate links and forwards them to template rendering. |
| packages/core/src/node/ssg/renderHtmlTemplate.ts | Injects alternate link tags at HEAD_MARKER and standardizes attribute spacing. |
| packages/core/src/node/ssg/alternateLinks.ts | Implements alternate link computation (grouping by route + version + language). |
| packages/core/src/node/ssg/alternateLinks.test.ts | Unit tests for alternate link generation + head injection. |
| e2e/fixtures/i18n/rspress.config.ts | Sets siteOrigin for deterministic absolute alternate-link URLs in build output. |
| e2e/fixtures/i18n/index.test.ts | Adds production-build assertions for reciprocal alternate links in generated HTML. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Deploying rspress-v2 with
|
| Latest commit: |
bad42d6
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://8797863c.rspress-v2.pages.dev |
| Branch Preview URL: | https://fix-i18n-alternate-links.rspress-v2.pages.dev |
0fcd680 to
351183d
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 351183dbf1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8bb6fab75b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef638a695a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
rel="alternate"andhreflanglinks to the document head for multilingual routes that actually exist.base,siteOrigin, androute.cleanUrlsacross SSG, CSR fallbacks, and the experimental SSG worker.Example
Given the following configuration:
When both
/guideand/zh/guideexist, Rspress adds the reciprocal links to both documents:Only translations that actually exist are included. Locale IDs containing underscores keep their route path while the generated
hreflangvalue uses hyphens:Related Issue
Related to #3512.
Checklist