feat(i18n): routing and localization infrastructure (phase 1)
Implement Phase 1 of i18n spec: - Configure next-intl with 6 locales (pt, en, es, fr, de, zh-CN) and pathnames - Move routes to app/[locale] structure with localized layouts and metadata - Add middleware for root language negotiation (307), legacy redirects (308), and 404 for non-pt book - Implement language selector dropdown in header with cookie persistence - Add system typography rules for zh-CN and word-break/hyphenation for de/fr Co-Authored-By: Antigravity <noreply@google.com>
This commit is contained in:
1 parent
e92aea0c84
commit
83c0ba3e74
38 files changed
+1699
-324
No files matched your search
@@ -92,6 +92,7 @@ function obterRotasExistentes() {
|
||||
if (arq.endsWith("page.jsx") || arq.endsWith("page.js")) {
|
||||
let rota = arq
|
||||
.replace(/^app/, "")
|
||||
.replace(/\/\[locale\]/, "")
|
||||
.replace(/\/page\.(jsx|js)$/, "");
|
||||
if (rota === "") rota = "/";
|
||||
rotas.add(rota);
|
||||
@@ -132,7 +133,12 @@ function auditarPerformanceConfigs() {
|
||||
|
||||
// Checar globals.css e layout.jsx para transições no body
|
||||
const globalsCss = existsSync("app/globals.css") ? readFileSync("app/globals.css", "utf8") : "";
|
||||
const layoutJsx = existsSync("app/layout.jsx") ? readFileSync("app/layout.jsx", "utf8") : "";
|
||||
const layoutPath = existsSync("app/[locale]/layout.jsx")
|
||||
? "app/[locale]/layout.jsx"
|
||||
: existsSync("app/layout.jsx")
|
||||
? "app/layout.jsx"
|
||||
: null;
|
||||
const layoutJsx = layoutPath ? readFileSync(layoutPath, "utf8") : "";
|
||||
|
||||
if (globalsCss.includes("body {\n\t\t@apply bg-slate-50 text-slate-900 transition-colors")) {
|
||||
falha("globals.css tem transition-colors global no body (provoca animações não compostas no load).");
|
||||
@@ -299,7 +305,8 @@ function auditarRotasInternas() {
|
||||
if (caminho.startsWith("/api") || caminho.startsWith("/favicon") || caminho.startsWith("/icon") || caminho.startsWith("/logo") || caminho.startsWith("/site.webmanifest")) {
|
||||
continue;
|
||||
}
|
||||
const existe = rotasValidas.has(caminho) || rotasDinamicas.some((rx) => rx.test(caminho));
|
||||
const caminhoSemLocale = caminho.replace(/^\/(?:pt|en|es|fr|de|zh-CN)(?=\/|$)/, "") || "/";
|
||||
const existe = rotasValidas.has(caminho) || rotasValidas.has(caminhoSemLocale) || rotasDinamicas.some((rx) => rx.test(caminho) || rx.test(caminhoSemLocale));
|
||||
if (!existe) {
|
||||
falha(`${arq} -> Link interno aponta para rota inexistente: '${caminho}'`);
|
||||
rotasQuebradas++;
|
||||
|
||||
Reference in new issue
Block a user