diff --git a/CHANGELOG.md b/CHANGELOG.md index 4176e25..deffcf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,38 @@ Tudo o que muda de relevante no ESPDocs está aqui. O formato segue o ## [Não lançado] +## [1.6.0] - 2026-11-02 + +### Adicionado + +- Chinês simplificado (`/zh-CN`), o sexto idioma do site, com o mesmo conteúdo dos + demais, menos o livro (`/zh-CN/livro` responde 404): + - Interface, séries, frameworks, diagramas de pinos, glossário, diagnóstico, + componentes e exemplos de código com comentários em chinês (mensagens de log + dos exemplos ficam em inglês, para não aparecerem quebradas no monitor serial). + - Busca em chinês: o motor entende consultas como `s3 闪存`, `c6 usb 引脚` ou + `哪款 esp32 有 psram`, segmentando o texto com `Intl.Segmenter`. + - SEO próprio (`hreflang`, sitemap, JSON-LD em `zh-CN`) e negociação da raiz: + `Accept-Language` com `zh`, `zh-Hans` ou `zh-TW` leva a `/zh-CN`. + - O filtro alfabético A–Z do glossário não aparece em chinês. +- `scripts/verifica-busca.mjs`, chamado pelo teste de fumaça: roda o motor de busca + sobre o índice de cada idioma e confere que as respostas e os links estão no + idioma da página. +- `check-i18n` passa a procurar português dentro dos dados dos outros idiomas. + +### Corrigido + +- Na busca, as respostas diretas (por exemplo "Flash no ESP32-S3", "Dados da série", + "Pinos do ESP32-S3 ligados à memória flash") saíam em português em inglês, espanhol, + francês e alemão, e levavam a `/series/...` em vez do idioma da página. Agora + textos e links seguem o idioma. +- Em francês e alemão, valores de ADC, SPI, toque capacitivo, consumo e outros ainda + estavam em português (por exemplo "até 18 canais", "conforme a carga"); em espanhol, + dois valores de consumo. Todos traduzidos. +- O seletor de chip reconhecia "Sim"/"Yes" para Matter, Arduino e segurança, mas não + "Sí", "Oui" nem "Ja"; agora reconhece os seis idiomas. +- A home em alemão mostrava "14 frameworks" em minúscula. + ## [1.5.0] - 2026-11-02 ### Adicionado @@ -194,7 +226,8 @@ entrada resume tudo desde o primeiro commit, em 2025-10-21, até a imagem Docker otimização de imagens (GHSA-2464-fhr4-w9xw), e `postcss` fixado acima da cópia embutida no `next`. -[Não lançado]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.5.0...HEAD +[Não lançado]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.6.0...HEAD +[1.6.0]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.5.0...v1.6.0 [1.5.0]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.4.2...v1.5.0 [1.4.2]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.4.1...v1.4.2 [1.4.1]: https://git.lucasrguerra.dev.br/lucasrguerra/ESPDocs/compare/v1.4.0...v1.4.1 diff --git a/app/[locale]/catalogo/layout.jsx b/app/[locale]/catalogo/layout.jsx index df49257..d8e5a51 100644 --- a/app/[locale]/catalogo/layout.jsx +++ b/app/[locale]/catalogo/layout.jsx @@ -6,15 +6,16 @@ export async function generateMetadata({ params }) { const isEs = locale === "es"; const isFr = locale === "fr"; const isDe = locale === "de"; + const isZh = locale === "zh-CN"; return paginaMeta({ - 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", + titulo: isEn ? "ESP32 Board Catalog" : isEs ? "Catálogo de placas ESP32" : isFr ? "Catalogue de cartes ESP32" : isZh ? "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 + : isZh ? "带有 ESP32 的开发板,可按系列、接口和 USB 转串口芯片筛选。" : 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", @@ -25,7 +26,7 @@ export async function generateMetadata({ params }) { ? ["placas ESP32", "DevKit ESP32", "comprar ESP32", "ESP32 DevKitC"] : isFr ? ["cartes ESP32", "DevKit ESP32", "acheter ESP32", "ESP32 DevKitC"] - : isDe + : isZh ? ["ESP32 开发板", "ESP32 DevKit", "购买 ESP32", "ESP32 DevKitC"] : isDe ? ["ESP32 Boards", "ESP32 DevKit", "ESP32 kaufen", "ESP32 DevKitC"] : ["placas ESP32", "DevKit ESP32", "comprar ESP32", "ESP32 DevKitC"], }); @@ -37,7 +38,8 @@ export default async function Layout({ children, params }) { const isEs = locale === "es"; const isFr = locale === "fr"; const isDe = locale === "de"; - const canonPath = isEn ? "/en/catalog" : isEs ? "/es/catalogo" : isFr ? "/fr/catalogue" : isDe ? "/de/katalog" : "/catalogo"; + const isZh = locale === "zh-CN"; + const canonPath = isEn ? "/en/catalog" : isEs ? "/es/catalogo" : isFr ? "/fr/catalogue" : isZh ? "/zh-CN/catalog" : isDe ? "/de/katalog" : "/catalogo"; return ( <> @@ -46,14 +48,14 @@ 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" : isFr ? "Catalogue de cartes de développement ESP32" : isDe ? "Katalog für ESP32-Entwicklungsboards" : "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" : isZh ? "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 + : isZh ? "带有 ESP32 微控制器的开发板与 DevKit 的交互式指南与目录。" : 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, @@ -67,8 +69,8 @@ export default async function Layout({ children, params }) { dangerouslySetInnerHTML={{ __html: JSON.stringify( jsonLd.trilha([ - { 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 }, + { nome: isEn ? "Home" : isEs ? "Inicio" : isFr ? "Accueil" : isZh ? "首页" : isDe ? "Startseite" : "Início", caminho: isEn ? "/en" : isEs ? "/es" : isFr ? "/fr" : isZh ? "/zh-CN" : isDe ? "/de" : "/" }, + { nome: isEn ? "Board Catalog" : isEs ? "Catálogo de placas" : isFr ? "Catalogue de cartes" : isZh ? "开发板目录" : isDe ? "Board-Katalog" : "Catálogo de Placas", caminho: canonPath }, ]) ), }} diff --git a/app/[locale]/catalogo/page.jsx b/app/[locale]/catalogo/page.jsx index 8c25f15..31c1363 100644 --- a/app/[locale]/catalogo/page.jsx +++ b/app/[locale]/catalogo/page.jsx @@ -101,12 +101,35 @@ const HEADER_MAP_DE = { "Botões": "Tasten", "LEDs": "LEDs", }; +const HEADER_MAP_ZH = { + "Nome": "名称", + "Descrição": "描述", + "Série": "系列", + "Loja Oficial": "官方商店", + "Fabricante": "制造商", + "Processador": "处理器", + "Memória Flash": "闪存", + "PSRAM": "PSRAM", + "Conector USB": "USB 接口", + "Interface USB": "USB 接口类型", + "Antena": "天线", + "Bateria": "电池", + "Display": "显示屏", + "Sensores": "传感器", + "Botões": "按键", + "LEDs": "LEDs", +}; const VALUE_MAP_DE = { "Sim": "Ja", "Não": "Nein", "Opcional": "Optional", }; +const VALUE_MAP_ZH = { + "Sim": "是", + "Não": "否", + "Opcional": "可选", +}; export default function PlacasPage() { const pathname = usePathname() || ""; @@ -114,6 +137,7 @@ export default function PlacasPage() { const isEs = pathname === "/es" || pathname.startsWith("/es/"); const isFr = pathname === "/fr" || pathname.startsWith("/fr/"); const isDe = pathname === "/de" || pathname.startsWith("/de/"); + const isZh = pathname === "/zh-CN" || pathname.startsWith("/zh-CN/"); const [boards, setBoards] = useState([]); const [filteredBoards, setFilteredBoards] = useState([]); @@ -142,7 +166,7 @@ export default function PlacasPage() { const response = await fetch("/api/placas"); if (!response.ok) { - throw new Error(isEn ? "Failed to load board data" : isEs ? "Error al cargar los datos de las placas" : isFr ? "Erreur lors du chargement des données des cartes" : isDe ? "Fehler beim Laden der Board-Daten" : "Erro ao carregar dados das placas"); + throw new Error(isEn ? "Failed to load board data" : isEs ? "Error al cargar los datos de las placas" : isFr ? "Erreur lors du chargement des données des cartes" : isZh ? "加载开发板数据出错" : isDe ? "Fehler beim Laden der Board-Daten" : "Erro ao carregar dados das placas"); } const result = await response.json(); @@ -248,11 +272,11 @@ export default function PlacasPage() { isEn={isEn} isEs={isEs} isFr={isFr} - isDe={isDe} - trail={[{ label: isEn ? "Board Catalog" : isEs ? "Catálogo de placas" : isFr ? "Catalogue de cartes" : isDe ? "Board-Katalog" : "Catálogo de placas" }]} + isDe={isDe} isZh={isZh} + trail={[{ label: isEn ? "Board Catalog" : isEs ? "Catálogo de placas" : isFr ? "Catalogue de cartes" : isZh ? "开发板目录" : isDe ? "Board-Katalog" : "Catálogo de placas" }]} icon={ShoppingCart} - label={isEn ? "Real DevKits and modules" : isEs ? "DevKits y módulos reales" : isFr ? "DevKits et modules réels" : isDe ? "Echte DevKits und Module" : "DevKits e módulos reais"} - title={isEn ? "ESP32 Board Catalog" : isEs ? "Catálogo de placas ESP32" : isFr ? "Catalogue de cartes ESP32" : isDe ? "ESP32-Board-Katalog" : "Catálogo de placas ESP32"} + label={isEn ? "Real DevKits and modules" : isEs ? "DevKits y módulos reales" : isFr ? "DevKits et modules réels" : isZh ? "真实的 DevKit 与模组" : isDe ? "Echte DevKits und Module" : "DevKits e módulos reais"} + title={isEn ? "ESP32 Board Catalog" : isEs ? "Catálogo de placas ESP32" : isFr ? "Catalogue de cartes ESP32" : isZh ? "ESP32 开发板目录" : isDe ? "ESP32-Board-Katalog" : "Catálogo de placas ESP32"} lede={ isEn ? "Compare official and third-party boards for your project: USB interface, on-board sensors and direct store links." @@ -260,7 +284,7 @@ export default function PlacasPage() { ? "Compare placas oficiales y alternativas para su proyecto: interfaz USB, sensores integrados y enlace directo a la tienda." : isFr ? "Comparez les cartes officielles et alternatives pour votre projet : interface USB, capteurs intégrés et lien direct vers la boutique." - : isDe + : isZh ? "对比官方与替代开发板,为你的项目选型:USB 接口、板载传感器,以及直达商店的链接。" : isDe ? "Vergleichen Sie offizielle und Drittanbieter-Boards für Ihr Projekt: USB-Schnittstelle, integrierte Sensoren und direkter Store-Link." : "Compare placas oficiais e alternativas para o seu projeto: interface USB, sensores integrados e link direto para a loja." } @@ -273,14 +297,14 @@ export default function PlacasPage() {
{hero} -
+
{Array.from({ length: 6 }).map((_, i) => (
))}

- {isEn ? "Querying boards database…" : isEs ? "Consultando la base de datos de placas…" : isFr ? "Consultation de la base de cartes…" : isDe ? "Board-Datenbank wird abgefragt…" : "Consultando o banco de placas…"} + {isEn ? "Querying boards database…" : isEs ? "Consultando la base de datos de placas…" : isFr ? "Consultation de la base de cartes…" : isZh ? "正在查询开发板数据库…" : isDe ? "Board-Datenbank wird abgefragt…" : "Consultando o banco de placas…"}

@@ -300,14 +324,14 @@ export default function PlacasPage() {