import { notFound } from "next/navigation"; import { JetBrains_Mono, Manrope, Space_Grotesk } from "next/font/google"; import { NextIntlClientProvider } from "next-intl"; import { getMessages } from "next-intl/server"; import { routing } from "@/i18n/routing"; import { ENABLED_LOCALES } from "@/i18n/links"; import "../globals.css"; import Providers from "@/components/Providers"; import { SITE, jsonLd } from "@/lib/seo"; const spaceGrotesk = Space_Grotesk({ subsets: ["latin"], variable: "--font-space-grotesk", display: "swap", weight: ["500", "600", "700"], }); const manrope = Manrope({ subsets: ["latin"], variable: "--font-manrope", display: "swap", weight: ["400", "500", "600", "700"], }); const jetbrainsMono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-jetbrains", display: "swap", weight: ["400", "500", "600"], }); const LANG_MAP = { pt: "pt-BR", en: "en", es: "es-419", fr: "fr", de: "de", "zh-CN": "zh-CN", }; export function generateStaticParams() { return ENABLED_LOCALES.map((locale) => ({ locale })); } 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"; const isZh = locale === "zh-CN"; const ogLocaleMap = { pt: "pt_BR", en: "en_US", es: "es_419", fr: "fr_FR", de: "de_DE", "zh-CN": "zh_CN", }; const alternateLocales = ENABLED_LOCALES.filter((l) => l !== locale).map((l) => ogLocaleMap[l]); const titleDefault = isEn ? "ESPDocs · ESP32 Open Documentation" : isEs ? "ESPDocs · Documentación abierta de ESP32" : isFr ? "ESPDocs · Documentation ouverte ESP32" : isZh ? "ESPDocs · ESP32 中文文档" : isDe ? "ESPDocs · Offene ESP32-Dokumentation" : "ESPDocs · Documentação do ESP32 em português"; const description = isEn ? "Specifications, pinouts, comparison and selection of 12 ESP32 microcontroller series. Datasheets, peripherals, hardware security and connection diagrams." : isEs ? "Especificaciones, patillaje, comparación y selección de las 12 series de microcontroladores ESP32. Hojas de datos, periféricos, seguridad en hardware y diagramas de conexión." : isFr ? "Spécifications, brochages, comparaison et sélection des 12 séries de microcontrôleurs ESP32. Fiches techniques, périphériques, sécurité matérielle et schémas de connexion." : isZh ? "ESP32 全部 12 个系列微控制器的规格、引脚、对比与选型,使用简体中文。含数据手册、外设、硬件安全与连接图。" : isDe ? "Spezifikationen, Pinbelegungen, Vergleich und Auswahl der 12 ESP32-Mikrocontrollerserien. Datenblätter, Peripheriegeräte, Hardwaresicherheit und Anschlussdiagramme." : "Especificações, pinagem, comparação e seleção das 12 séries de microcontroladores ESP32, em português brasileiro. Datasheets, periféricos, segurança em hardware e diagramas de conexão."; const keywords = isEn ? [ "ESP32", "ESP32 documentation", "ESP32 pinout", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2", "compare ESP32", "which ESP32 to choose", "ESP32 datasheet", "microcontroller", "Espressif", "ESP-IDF", "IoT", "embedded systems", ] : isEs ? [ "ESP32", "ESP32 en español", "documentación ESP32", "patillaje ESP32", "pinout ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2", "comparar ESP32", "cuál ESP32 elegir", "datasheet ESP32", "hoja de datos ESP32", "microcontrolador", "Espressif", "ESP-IDF", "IoT", "sistemas embebidos", ] : isFr ? [ "ESP32", "ESP32 en français", "documentation ESP32", "brochage ESP32", "pinout ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2", "comparer ESP32", "quel ESP32 choisir", "datasheet ESP32", "fiche technique ESP32", "microcontrôleur", "Espressif", "ESP-IDF", "IoT", "systèmes embarqués", ] : isZh ? ["ESP32", "ESP32 中文", "ESP32 文档", "ESP32 引脚图", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2", "ESP32 对比", "ESP32 怎么选", "ESP32 数据手册", "微控制器", "乐鑫", "ESP-IDF", "物联网", "嵌入式系统"] : isDe ? [ "ESP32", "ESP32 auf Deutsch", "ESP32 Dokumentation", "ESP32 Pinbelegung", "ESP32 Pinout", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2", "ESP32 vergleichen", "welchen ESP32 wählen", "ESP32 Datenblatt", "Mikrocontroller", "Espressif", "ESP-IDF", "IoT", "eingebettete Systeme", ] : [ "ESP32", "ESP32 português", "documentação ESP32", "pinout ESP32", "ESP32-S3", "ESP32-C3", "ESP32-C6", "ESP32-P4", "ESP32-H2", "comparar ESP32", "qual ESP32 escolher", "datasheet ESP32", "microcontrolador", "Espressif", "ESP-IDF", "IoT", "sistemas embarcados", ]; const languages = Object.fromEntries( ENABLED_LOCALES.map((l) => [LANG_MAP[l] || l, `/${l}`]) ); if (ENABLED_LOCALES.includes("en")) { languages["x-default"] = "/en"; } return { metadataBase: new URL(SITE.url), title: { default: titleDefault, template: "%s · ESPDocs", }, description, applicationName: "ESPDocs", authors: [{ name: "Lucas Rayan Guerra", url: "https://lucasrguerra.dev.br" }], creator: "Lucas Rayan Guerra", publisher: "Ciência Embarcada", category: "technology", keywords, alternates: { canonical: `/${locale}`, languages, }, openGraph: { type: "website", locale: ogLocaleMap[locale] || "pt_BR", alternateLocale: alternateLocales.length > 0 ? alternateLocales : undefined, url: `${SITE.url}/${locale}`, siteName: SITE.nome, title: titleDefault, description: isEn ? "Specifications, pinouts, comparison and selection of 12 ESP32 microcontroller series." : isEs ? "Especificaciones, patillaje, comparación y selección de las 12 series de microcontroladores ESP32." : isFr ? "Spécifications, brochages, comparaison et sélection des 12 séries de microcontrôleurs ESP32." : isZh ? "ESP32 全部 12 个系列微控制器的规格、引脚、对比与选型,使用简体中文。" : isDe ? "Spezifikationen, Pinbelegungen, Vergleich und Auswahl der 12 ESP32-Mikrocontrollerserien." : "Especificações, pinagem, comparação e seleção das 12 séries de microcontroladores ESP32, em português brasileiro.", }, twitter: { card: "summary_large_image", title: titleDefault, description: isEn ? "Specifications, pinouts, comparison and selection of 12 ESP32 series." : isEs ? "Especificaciones, patillaje, comparación y selección de las 12 series de ESP32." : isFr ? "Spécifications, brochages, comparaison et sélection des 12 séries ESP32." : isZh ? "ESP32 全部 12 个系列的规格、引脚、对比与选型,使用简体中文。" : isDe ? "Spezifikationen, Pinbelegungen, Vergleich und Auswahl der 12 ESP32-Serien." : "Especificações, pinagem, comparação e seleção das 12 séries de ESP32, em português.", }, robots: { index: true, follow: true, googleBot: { index: true, follow: true, "max-image-preview": "large", "max-snippet": -1, "max-video-preview": -1, }, }, icons: { icon: [ { url: "/favicon.ico", sizes: "48x48", type: "image/x-icon" }, { url: "/favicon-48x48.png", sizes: "48x48", type: "image/png" }, { url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" }, { url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" }, { url: "/icon-192.png", sizes: "192x192", type: "image/png" }, { url: "/icon-512.png", sizes: "512x512", type: "image/png" }, { url: "/icon.svg", type: "image/svg+xml" }, ], apple: [ { url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" }, ], shortcut: "/favicon.ico", }, manifest: "/site.webmanifest", formatDetection: { telephone: false, address: false, email: false }, }; } export const viewport = { themeColor: [ { media: "(prefers-color-scheme: light)", color: "#f5f6f8" }, { media: "(prefers-color-scheme: dark)", color: "#07090d" }, ], }; export default async function RootLayout({ children, params }) { const { locale } = await params; if (!ENABLED_LOCALES.includes(locale)) { notFound(); } const lang = LANG_MAP[locale] || locale; const messages = await getMessages(); return ( {/* Dados estruturados do site e da organização. É o que permite ao Google montar o box de busca interna e entender a autoria. */}