feat(compare): Chinese (zh) locale for /compare and /compare-per-dollar#427
Open
functionstackx wants to merge 1 commit into
Open
feat(compare): Chinese (zh) locale for /compare and /compare-per-dollar#427functionstackx wants to merge 1 commit into
functionstackx wants to merge 1 commit into
Conversation
Adds a Chinese-language variant of the compare master + detail pages, served under a /zh URL prefix. No i18n framework existed, so this uses parallel routes that reuse the same React components with a `lang` prop and a Chinese dictionary — English routes are untouched and byte-identical. New URLs: /zh/compare /zh/compare/<slug> /zh/compare-per-dollar /zh/compare-per-dollar/<slug> What's translated (per scope decision — "compare copy only"): - Index headings, lede, vendor-group descriptions, per-dollar CTA - Detail eyebrow, description, H1, empty states, cross-links, pricing line, figcaption, caveat - SSR narrative prose (full Chinese template pools, 1:1 with the English pools) - Interpolated-table header + metric display labels (keys stay English so filtering/React keys are language-independent) - SEO metadata (title/description) + hreflang alternates, JSON-LD ItemList / Dataset / BreadcrumbList human-readable fields The embedded interactive chart (shared app-wide InferenceChartDisplay) stays English, as agreed. Implementation: - lib/compare/i18n.ts: Lang type, locale path helpers, en/zh dictionary - lib/compare-ssr.ts: threaded `lang` through formatModelList, compareTableNarrative (+ Chinese template pools), buildJsonLd, buildBreadcrumbJsonLd — English output unchanged when lang='en' - Extracted shared server views (index-view, full-detail-view, per-dollar-detail-view) so en + zh routes share slug parsing, the 308 canonicalization redirect (now locale-aware), the benchmark fetch, and the SSR interpolation. English route files are now thin wrappers. - Moved the two page-client components into lib/compare/ and made them + compare-interpolated-table lang-aware (dict for simple strings, inline JSX branch for the few markup-rich sentences). - Reused the canonical English performance-per-dollar.png hero/OG graphic for zh (language-neutral data graphic) rather than duplicating the ~500-line Satori route. - sitemap.ts: emit the zh index + detail URLs. Tests: added cypress/e2e/compare-zh.cy.ts (zh index + detail + per-dollar: localized copy, table, chart mount, locale-correct cross-links). Verified: prod build registers all four /zh routes (dynamic); zh + en index pages render at runtime; zh alias slug 308-redirects to the canonical zh URL; all 2006 app unit tests pass; typecheck + lint clean. (Detail-page data fetch needs the Vercel Blob token, absent locally — that path 500s identically for en and zh, so it's an env limitation, exercised by Cypress in CI.) Note: pages render under the root layout's <html lang="en">; per-page html lang isn't overridable without a root-layout change. hreflang alternates carry the locale signal for crawlers instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a Chinese-language version of the compare master pages and their detail subpages, served under a
/zhURL prefix:/compare/zh/compare/compare/<slug>/zh/compare/<slug>/compare-per-dollar/zh/compare-per-dollar/compare-per-dollar/<slug>/zh/compare-per-dollar/<slug>There is no i18n framework in the repo, so this uses parallel routes that reuse the same React components with a
langprop + a Chinese dictionary. The English routes are untouched and render byte-identically.Scope (per agreed decisions)
/zhroute prefix (no framework / middleware).InferenceChartDisplay, shared app-wide) stays English.What's translated
hreflangalternates (en/zh-CN); JSON-LDItemList/Dataset/BreadcrumbListhuman-readable fields; locale-aware breadcrumb index URLsImplementation notes
lib/compare/i18n.ts—Langtype, locale path helpers, en/zh dictionary (English entries copied verbatim from the old hard-coded pages).lib/compare-ssr.ts— threadedlangthroughformatModelList,compareTableNarrative,buildJsonLd,buildBreadcrumbJsonLd; English output unchanged whenlang='en'.index-view,full-detail-view,per-dollar-detail-view) so en + zh share slug parsing, the 308 canonicalization redirect (now locale-aware), the benchmark fetch, and the SSR interpolation. The original en route files are now thin wrappers. The twopage-client.tsxcomponents moved intolib/compare/and gained alangprop (dict for simple strings; inlinelang === 'zh'JSX branch for the few markup-rich sentences where word order differs).performance-per-dollar.pngendpoint rather than duplicating the ~500-line Satori route.Tests
cypress/e2e/compare-zh.cy.ts— zh index + detail + per-dollar: localized copy renders, interpolated table renders with localized labels, the interactive chart mounts, and cross-links stay within the zh locale.Verification
pnpm buildregisters all four/zhroutes (dynamic); English routes intact./zh/compareand/zh/compare-per-dollarreturn 200 with Chinese copy; the zh alias slug 308-redirects to the canonical zh URL;/compare(en) unchanged.pnpm test:unit— all 2006 app tests pass. Typecheck + lint clean.Known limitation
compare-table.cy.tsalready hits detail pages).<html lang="en">; a per-pagehtml langisn't overridable without changing the root layout. Thehreflangalternates carry the locale signal for crawlers instead.🤖 Generated with Claude Code
Note
Medium Risk
Broad refactor of high-traffic compare SSR/metadata and redirects; regressions could affect English SEO or canonical URLs, though English strings are intended to stay byte-identical.
Overview
Adds Chinese (
/zh) compare routes that mirror/compareand/compare-per-dollar(index + slug detail), using the same components with alangprop and a newlib/compare/i18n.tsdictionary plus locale path helpers.English compare pages are refactored into thin route wrappers that delegate to shared
CompareIndexView,FullDetailView, andPerDollarDetailView, so slug parsing, 308 canonical redirects (now locale-scoped), benchmark SSR, and JSON-LD stay unified. Copy, metadatahreflangalternates (en/zh-CN), SSR narrative template pools, breadcrumbs/JSON-LD labels, interpolated table UI strings, sitemap entries, and Cypress smoke tests (compare-zh.cy.ts) are wired for zh; the embedded inference chart remains English.Reviewed by Cursor Bugbot for commit 7b73b58. Bugbot is set up for automated code reviews on this repo. Configure here.