Files
ESPDocs/i18n/links.js
T
Lucas RayanandAntigravity dcd4ef7e1b
CI / Lint e auditorias (push) Successful in 44s
CI / Trivy (dependências e segredos) (push) Successful in 9s
CI / Imagem Docker (linux/arm64) (push) Successful in 3m56s
fix(i18n): extract navigation links module and restore verbatim pt footer
- Move getLocalizedHref, LOCALES, and CANONICAL_ROUTES to i18n/links.js to resolve SSR 500 error on home
- Import from @/i18n/links in page.jsx, Header.jsx, Footer.jsx, and LanguageSelector.jsx
- Restore exact production footer texts, author links, and SVG icons in pt
- Verify 100% visible text parity on all pt pages against production with cmp-pt.py

Co-Authored-By: Antigravity <noreply@google.com>
2026-11-01 10:19:22 -03:00

130 lines
4.0 KiB
JavaScript

/**
* Utilitários de rotas e navegação internacionalizada.
* Módulo puro (sem 'use client') seguro para Server e Client Components.
*/
export const LOCALES = [
{ code: "pt", label: "Português", short: "PT", lang: "pt-BR" },
{ code: "en", label: "English", short: "EN", lang: "en" },
{ code: "es", label: "Español", short: "ES", lang: "es-419" },
{ code: "fr", label: "Français", short: "FR", lang: "fr" },
{ code: "de", label: "Deutsch", short: "DE", lang: "de" },
{ code: "zh-CN", label: "简体中文", short: "中", lang: "zh-CN" },
];
export const CANONICAL_ROUTES = [
{
id: "series_item",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:series|serien)\/([^/]+)/,
getSlug: (loc, key) => (loc === "de" ? `/serien/${key}` : `/series/${key}`),
},
{
id: "frameworks_item",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/frameworks\/([^/]+)/,
getSlug: (loc, key) => `/frameworks/${key}`,
},
{
id: "series",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:series|serien)(?:\/|$)/,
getSlug: (loc) => (loc === "de" ? "/serien" : "/series"),
},
{
id: "catalogo",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:catalogo|catalog|catalogue|katalog)(?:\/|$)/,
getSlug: (loc) => {
if (loc === "de") return "/katalog";
if (loc === "fr") return "/catalogue";
if (loc === "en" || loc === "zh-CN") return "/catalog";
return "/catalogo";
},
},
{
id: "comparacao",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:comparacao|compare|comparacion|comparaison|vergleich)(?:\/|$)/,
getSlug: (loc) => {
if (loc === "en" || loc === "zh-CN") return "/compare";
if (loc === "es") return "/comparacion";
if (loc === "fr") return "/comparaison";
if (loc === "de") return "/vergleich";
return "/comparacao";
},
},
{
id: "componentes",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:componentes|components|composants|komponenten)(?:\/|$)/,
getSlug: (loc) => {
if (loc === "en" || loc === "zh-CN") return "/components";
if (loc === "fr") return "/composants";
if (loc === "de") return "/komponenten";
return "/componentes";
},
},
{
id: "diagnostico",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:diagnostico|diagnostics|diagnostic|diagnose)(?:\/|$)/,
getSlug: (loc) => {
if (loc === "en" || loc === "zh-CN") return "/diagnostics";
if (loc === "fr") return "/diagnostic";
if (loc === "de") return "/diagnose";
return "/diagnostico";
},
},
{
id: "frameworks",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/frameworks(?:\/|$)/,
getSlug: () => "/frameworks",
},
{
id: "glossario",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:glossario|glossary|glosario|glossaire|glossar)(?:\/|$)/,
getSlug: (loc) => {
if (loc === "en" || loc === "zh-CN") return "/glossary";
if (loc === "es") return "/glosario";
if (loc === "fr") return "/glossaire";
if (loc === "de") return "/glossar";
return "/glossario";
},
},
{
id: "seletor",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:seletor|selector|selecteur|auswahl)(?:\/|$)/,
getSlug: (loc) => {
if (loc === "en" || loc === "es" || loc === "zh-CN") return "/selector";
if (loc === "fr") return "/selecteur";
if (loc === "de") return "/auswahl";
return "/seletor";
},
},
{
id: "sobre",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/(?:sobre|about|acerca|a-propos|ueber-uns)(?:\/|$)/,
getSlug: (loc) => {
if (loc === "en" || loc === "zh-CN") return "/about";
if (loc === "es") return "/acerca";
if (loc === "fr") return "/a-propos";
if (loc === "de") return "/ueber-uns";
return "/sobre";
},
},
{
id: "livro",
match: /^\/(?:pt|en|es|fr|de|zh-CN)\/livro(?:\/|$)/,
getSlug: (loc) => (loc === "pt" ? "/livro" : ""),
},
];
export function getLocalizedHref(pathname, targetLocale) {
if (!pathname || pathname === "/" || pathname === `/${targetLocale}` || pathname === `/${targetLocale}/`) {
return `/${targetLocale}/`;
}
for (const route of CANONICAL_ROUTES) {
const m = pathname.match(route.match);
if (m) {
const slug = route.getSlug(targetLocale, m[1]);
return slug ? `/${targetLocale}${slug}` : `/${targetLocale}/`;
}
}
return `/${targetLocale}/`;
}