--- title: "Language route prefixes — short ISO codes with legacy redirects" type: quick-fix date: 2026-06-04 --- # Language route prefixes — short ISO codes with legacy redirects ## Bug Localized URLs used full English names (`/chinese`, `/japanese`, `/korean`, `/vietnamese`, `/indonesian`, `/malay`). Per the broadcast in WeChat (screenshot), they need to be short ISO-style codes (`/cn`, `/ja`, `/ko`, `/vi`, `/id`, `/ms`). ## Root Cause The mapping is sourced from one place — `src/languageRoutes.ts` `localizedHomeRoutes` — and that array hard-coded the long names. ## Fix - Rename every localized prefix in `localizedHomeRoutes` to its short code. - Add `legacyLanguageRedirects` (the old → new map) and render client redirects in `App.tsx` so links previously shared (`/chinese`, `/malay/browse?post=42`, etc.) keep landing on the right destination. The redirect preserves sub-path, query string, and hash. - Refresh doc-comment examples (`/malay/...`) in unrelated files so future readers don't get confused. - Update `languageRoutes.test.ts` to assert the new mapping. ### Files Modified - `src/languageRoutes.ts` — paths swapped to short codes; added `legacyLanguageRedirects`; refreshed doc-comment examples. - `src/languageRoutes.test.ts` — expectations updated to short codes; test description renamed accordingly. - `src/App.tsx` — added `LegacyLangRedirect` component (uses `useParams`/`useLocation`) and rendered `` pairs (`/old` and `/old/*`) for each entry in `legacyLanguageRedirects`. - `src/i18n.tsx`, `src/components/FigmaBanner.tsx`, `src/layouts/PublicLayout.tsx`, `src/useLocalizedPath.ts` — doc-comment example paths updated for consistency. ## Verification - `npx tsc --noEmit` — clean. - `npm run format` then `npm run format:check` — clean. - `npm test` — 49/49 passing (includes the updated `languageRoutes.test.ts`). - Expected runtime behavior: - `/cn`, `/ja`, `/ko`, `/vi`, `/id`, `/ms` (and their nested routes) resolve to localized pages. - `/chinese`, `/japanese`, `/korean`, `/vietnamese`, `/indonesian`, `/malay` (and their nested routes) redirect via React Router `` to the new short-code equivalents, preserving `?query` and `#hash`. ## Notes - Server-side considerations: this works for SPA navigation because BrowserRouter handles all paths client-side. Any reverse-proxy/CDN rule that hardcoded the long names should be reviewed (e.g. nginx rewrites, prerender configs). The `nginx.conf` and Gitea deploy workflow only reference `index.html`, so no server-side path rules to update here. - If the SEO sitemap / canonical URLs are generated elsewhere, those should also pick up the new prefixes. - `legacyLanguageRedirects` is intentionally kept distinct from `localizedHomeRoutes` so we can sunset it later by deleting the export and the corresponding routes block in `App.tsx`.