feat(i18n): French and German localization (phase 5)
CI / Lint e auditorias (push) Successful in 49s
CI / Trivy (dependências e segredos) (push) Successful in 11s
CI / Imagem Docker (linux/arm64) (push) Successful in 3m14s

- Add full message catalogs and content for French (fr) and German (de)
- Implement ASCII canonical slugs for French and German routes
- Add language-specific search endpoints (/api/busca/fr, /api/busca/de)
- Configure strict 404 responses for /fr/livro and /de/livro
- Localize SEO, OpenGraph (fr_FR, de_DE), Twitter and JSON-LD schemas
- Add localized code example comments across 14 examples for fr and de
- Enable 'fr' and 'de' in ENABLED_LOCALES with root negotiation and redirect
- Extend test suite in check-i18n, smoke-imagem and verifica-vazamentos

Co-Authored-By: Antigravity <noreply@google.com>
This commit is contained in:
Lucas RayanandAntigravity committed 2026-11-01 22:06:36 -03:00
1 parent 7b673aeb4b
commit 7fce46b9e1
104 files changed
+33369 -686

No files matched your search

+21 -5
View File
@@ -4,12 +4,18 @@ export async function generateMetadata({ params }) {
const { locale } = await params;
const isEn = locale === "en";
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
return paginaMeta({
titulo: isEn ? "ESP32 Board Catalog" : isEs ? "Catálogo de placas ESP32" : "Catálogo de placas ESP32",
titulo: isEn ? "ESP32 Board Catalog" : isEs ? "Catálogo de placas ESP32" : isFr ? "Catalogue de cartes ESP32" : isDe ? "ESP32-Board-Katalog" : "Catálogo de placas ESP32",
descricao: isEn
? "ESP32 development boards and DevKits available in Brazil, with filters by series, connector, and USB-serial converter."
: isEs
? "Placas de desarrollo y DevKits con ESP32, con filtros por serie, conector y conversor USB-serial."
: isFr
? "Cartes de développement et DevKits ESP32, avec filtres par série, connecteur et convertisseur USB-série."
: isDe
? "ESP32-Entwicklungsboards und DevKits, mit Filtern nach Serie, Anschluss und USB-Seriell-Wandler."
: "Placas de desenvolvimento com ESP32 disponíveis no Brasil, com filtro por série, conector e conversor USB-serial.",
caminho: "/catalogo",
locale,
@@ -17,6 +23,10 @@ export async function generateMetadata({ params }) {
? ["ESP32 boards", "ESP32 DevKit", "buy ESP32", "ESP32 DevKitC"]
: isEs
? ["placas ESP32", "DevKit ESP32", "comprar ESP32", "ESP32 DevKitC"]
: isFr
? ["cartes ESP32", "DevKit ESP32", "acheter ESP32", "ESP32 DevKitC"]
: isDe
? ["ESP32 Boards", "ESP32 DevKit", "ESP32 kaufen", "ESP32 DevKitC"]
: ["placas ESP32", "DevKit ESP32", "comprar ESP32", "ESP32 DevKitC"],
});
}
@@ -25,7 +35,9 @@ export default async function Layout({ children, params }) {
const { locale } = await params;
const isEn = locale === "en";
const isEs = locale === "es";
const canonPath = isEn ? "/en/catalog" : isEs ? "/es/catalogo" : "/catalogo";
const isFr = locale === "fr";
const isDe = locale === "de";
const canonPath = isEn ? "/en/catalog" : isEs ? "/es/catalogo" : isFr ? "/fr/catalogue" : isDe ? "/de/katalog" : "/catalogo";
return (
<>
@@ -34,11 +46,15 @@ export default async function Layout({ children, params }) {
dangerouslySetInnerHTML={{
__html: JSON.stringify(
jsonLd.aplicacaoWeb({
nome: isEn ? "ESP32 Development Board Catalog" : isEs ? "Catálogo de placas de desarrollo ESP32" : "Catálogo de Placas ESP32",
nome: isEn ? "ESP32 Development Board Catalog" : isEs ? "Catálogo de placas de desarrollo ESP32" : isFr ? "Catalogue de cartes de développement ESP32" : isDe ? "Katalog für ESP32-Entwicklungsboards" : "Catálogo de Placas ESP32",
descricao: isEn
? "Interactive guide and catalog of development boards and DevKits featuring ESP32 microcontrollers."
: isEs
? "Guía y catálogo interactivo de placas de desarrollo y DevKits con microcontroladores ESP32."
: isFr
? "Guide interactif et catalogue de cartes de développement et DevKits avec microcontrôleurs ESP32."
: isDe
? "Interaktiver Leitfaden und Katalog für Entwicklungsboards und DevKits mit ESP32-Mikrocontrollern."
: "Guia e catálogo interativo de placas de desenvolvimento e DevKits com microcontroladores ESP32.",
caminho: canonPath,
locale,
@@ -51,8 +67,8 @@ export default async function Layout({ children, params }) {
dangerouslySetInnerHTML={{
__html: JSON.stringify(
jsonLd.trilha([
{ nome: isEn ? "Home" : isEs ? "Inicio" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : "/" },
{ nome: isEn ? "Board Catalog" : isEs ? "Catálogo de placas" : "Catálogo de Placas", caminho: canonPath },
{ nome: isEn ? "Home" : isEs ? "Inicio" : isFr ? "Accueil" : isDe ? "Startseite" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : isFr ? "/fr" : isDe ? "/de" : "/" },
{ nome: isEn ? "Board Catalog" : isEs ? "Catálogo de placas" : isFr ? "Catalogue de cartes" : isDe ? "Board-Katalog" : "Catálogo de Placas", caminho: canonPath },
])
),
}}