/** * Fonte única das informações de SEO do ESPDocs. * * Centralizar aqui evita o problema clássico de metadata espalhado: a URL do * site aparecendo com valores diferentes em cada arquivo, ou uma página nova * nascendo sem título próprio. */ export const SITE = { url: "https://espdocs.cienciaembarcada.com.br", nome: "ESPDocs", autor: "Lucas Rayan Guerra", autorUrl: "https://lucasrguerra.dev.br", autorLinkedin: "https://linkedin.com/in/lucasrguerra", autorEmail: "contato@lucasrguerra.dev.br", repositorio: "https://github.com/lucasrguerra/ESPDocs", blog: "https://cienciaembarcada.com.br", livroTitulo: "Microcontroladores ESP32", livroSubtitulo: "Conectividade, Eficiência e Desempenho", livroIsbn: "978-65-02-43432-1", livroCapa: "/livro/capa.jpg", livroAmazon: "https://a.co/d/0fdCvzlg", livroUiclap: "https://loja.uiclap.com/titulo/ua213708", }; /** * Monta o objeto `metadata` de uma página, já com canonical e Open Graph. * Usar isto em vez de escrever o objeto à mão garante que nenhuma página fique * sem canonical ou sem og:title. */ export function paginaMeta({ titulo, descricao, caminho, keywords = [], tipo = "website" }) { const url = `${SITE.url}${caminho}`; return { title: titulo, description: descricao, keywords, alternates: { canonical: caminho }, openGraph: { type: tipo, locale: "pt_BR", url, siteName: SITE.nome, title: `${titulo} · ${SITE.nome}`, description: descricao, }, twitter: { card: "summary_large_image", title: `${titulo} · ${SITE.nome}`, description: descricao, }, }; } /* ------------------------------------------------------------------------ Dados estruturados (JSON-LD). São eles que rendem os resultados ricos: trilha de navegação, box de busca e reconhecimento de autoria. ------------------------------------------------------------------------ */ export const jsonLd = { siteESociedade() { return { "@context": "https://schema.org", "@graph": [ { "@type": "WebSite", "@id": `${SITE.url}/#site`, url: SITE.url, name: SITE.nome, inLanguage: "pt-BR", description: "Documentação do ecossistema ESP32 em português brasileiro: especificações, pinagem, comparação e seleção de séries.", publisher: { "@id": `${SITE.url}/#organizacao` }, }, { "@type": "Organization", "@id": `${SITE.url}/#organizacao`, name: "Ciência Embarcada", url: SITE.blog, logo: { "@type": "ImageObject", url: `${SITE.url}/icon-512.png`, width: 512, height: 512, }, image: `${SITE.url}/icon-512.png`, sameAs: [SITE.autorLinkedin, SITE.repositorio, SITE.blog], }, { "@type": "Person", "@id": `${SITE.url}/#autor`, name: SITE.autor, url: SITE.autorUrl, email: SITE.autorEmail, sameAs: [SITE.autorLinkedin, SITE.repositorio, SITE.blog], }, ], }; }, /** Trilha de navegação: aparece acima do título no resultado de busca. */ trilha(itens) { return { "@context": "https://schema.org", "@type": "BreadcrumbList", itemListElement: itens.map((it, i) => ({ "@type": "ListItem", position: i + 1, name: it.nome, item: `${SITE.url}${it.caminho}`, })), }; }, /** Documentação e ficha técnica da série como TechArticle para o Google. */ serie(chave, serie) { const prop = (nome, valor) => valor ? { "@type": "PropertyValue", name: nome, value: String(valor) } : null; const propriedades = [ prop("Fabricante", "Espressif Systems"), prop("Arquitetura", serie.arquitetura), prop("Núcleos", serie.nucleos), prop("Frequência máxima", serie.frequencia), prop("SRAM", serie.memoria_sram), prop("RTC SRAM", serie.memoria_sram_rtc), prop("Flash suportada", serie.flash_suportada), prop("PSRAM suportada", serie.psram_suportada), prop("GPIO", serie.gpio), prop("Wi-Fi", serie.wifi), prop("Bluetooth", serie.bluetooth), prop("Zigbee / Thread / 802.15.4", serie.zigbee_thread), prop("Encapsulamento", serie.encapsulamento), prop("ESP-IDF mínimo", serie.esp_idf_minimo), ].filter(Boolean); const imagem = serie.placa ? `${SITE.url}${serie.placa}` : `${SITE.url}/opengraph-image.png`; return { "@context": "https://schema.org", "@type": "TechArticle", "@id": `${SITE.url}/series/${chave}#artigo`, headline: `${serie.nome_completo || chave}: especificações e pinagem`, name: `${serie.nome_completo || chave} - Documentação Técnica e Especificações`, description: serie.descricao, image: [imagem], inLanguage: "pt-BR", datePublished: "2026-08-25T00:00:00.000Z", dateModified: new Date().toISOString(), mainEntityOfPage: `${SITE.url}/series/${chave}`, url: `${SITE.url}/series/${chave}`, author: { "@type": "Person", name: SITE.autor, url: SITE.autorUrl, }, publisher: { "@type": "Organization", name: "Ciência Embarcada", url: SITE.blog, logo: { "@type": "ImageObject", url: `${SITE.url}/icon-512.png`, width: 512, height: 512, }, }, about: { "@type": "Thing", name: serie.nome_completo || chave, description: serie.descricao, additionalProperty: propriedades, }, }; }, /** Documentação técnica de framework. */ framework(chave, framework) { return { "@context": "https://schema.org", "@type": "TechArticle", "@id": `${SITE.url}/frameworks/${encodeURIComponent(chave)}#artigo`, headline: `${framework.nome} para ESP32: Guia e Documentação`, name: `${framework.nome_completo || framework.nome} para ESP32`, description: framework.descricao, image: [`${SITE.url}/opengraph-image.png`], inLanguage: "pt-BR", datePublished: "2026-08-25T00:00:00.000Z", dateModified: new Date().toISOString(), mainEntityOfPage: `${SITE.url}/frameworks/${encodeURIComponent(chave)}`, url: `${SITE.url}/frameworks/${encodeURIComponent(chave)}`, author: { "@type": "Person", name: SITE.autor, url: SITE.autorUrl, }, publisher: { "@type": "Organization", name: "Ciência Embarcada", url: SITE.blog, logo: { "@type": "ImageObject", url: `${SITE.url}/icon-512.png`, width: 512, height: 512, }, }, about: { "@type": "SoftwareApplication", name: framework.nome_completo || framework.nome, applicationCategory: "DeveloperApplication", operatingSystem: "Embedded", description: framework.descricao, url: framework.documentacao || `${SITE.url}/frameworks/${encodeURIComponent(chave)}`, }, }; }, /** Glossário: marca cada verbete como termo definido. */ glossario(categorias) { return { "@context": "https://schema.org", "@type": "DefinedTermSet", "@id": `${SITE.url}/glossario#glossario`, name: "Glossário Técnico do ESP32", inLanguage: "pt-BR", hasDefinedTerm: categorias.flatMap((cat) => cat.termos.map((t) => ({ "@type": "DefinedTerm", name: t.termo, description: t.definicao, inDefinedTermSet: `${SITE.url}/glossario#glossario`, })) ), }; }, /** Perguntas frequentes: pode render o bloco expansível no Google. */ perguntas(pares) { return { "@context": "https://schema.org", "@type": "FAQPage", mainEntity: pares.map(({ pergunta, resposta }) => ({ "@type": "Question", name: pergunta, acceptedAnswer: { "@type": "Answer", text: resposta }, })), }; }, /** Aplicação web / ferramenta interativa (Seletor, Comparador, Catálogo). */ aplicacaoWeb({ nome, descricao, caminho }) { return { "@context": "https://schema.org", "@type": "WebApplication", "@id": `${SITE.url}${caminho}#app`, name: nome, description: descricao, url: `${SITE.url}${caminho}`, applicationCategory: "DeveloperApplication", operatingSystem: "All", browserRequirements: "Requires JavaScript", inLanguage: "pt-BR", author: { "@type": "Person", name: SITE.autor, url: SITE.autorUrl, }, publisher: { "@type": "Organization", name: "Ciência Embarcada", url: SITE.blog, logo: { "@type": "ImageObject", url: `${SITE.url}/icon-512.png`, width: 512, height: 512, }, }, offers: { "@type": "Offer", price: "0", priceCurrency: "BRL", }, }; }, /** Livro do autor: dados de obra para mecanismos de busca. */ livro() { return { "@context": "https://schema.org", "@type": "Book", "@id": `${SITE.url}/livro#livro`, name: SITE.livroTitulo, alternateName: `${SITE.livroTitulo}: ${SITE.livroSubtitulo}`, description: "Livro em português sobre o hardware e o firmware do ESP32: arquitetura, energia, rádio, periféricos e projeto de produto, em 12 partes e 78 capítulos.", inLanguage: "pt-BR", url: `${SITE.url}/livro`, isbn: SITE.livroIsbn, image: `${SITE.url}${SITE.livroCapa}`, author: { "@type": "Person", name: SITE.autor, url: SITE.autorUrl, }, publisher: { "@type": "Organization", name: "Ciência Embarcada", url: SITE.blog, }, about: [ { "@type": "Thing", name: "ESP32" }, { "@type": "Thing", name: "Sistemas embarcados" }, { "@type": "Thing", name: "Internet das Coisas" }, ], workExample: [ { "@type": "Book", "@id": `${SITE.url}/livro#digital`, bookFormat: "https://schema.org/EBook", url: SITE.livroAmazon, potentialAction: { "@type": "BuyAction", target: SITE.livroAmazon, }, }, { "@type": "Book", "@id": `${SITE.url}/livro#fisico`, bookFormat: "https://schema.org/Paperback", url: SITE.livroUiclap, potentialAction: { "@type": "BuyAction", target: SITE.livroUiclap, }, }, ], }; }, /** Página Sobre com metadados E-E-A-T de autoria e reputação. */ paginaSobre() { return { "@context": "https://schema.org", "@type": "AboutPage", "@id": `${SITE.url}/sobre#sobre`, name: "Sobre o ESPDocs", description: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro.", url: `${SITE.url}/sobre`, inLanguage: "pt-BR", mainEntity: { "@type": "Person", name: SITE.autor, url: SITE.autorUrl, email: SITE.autorEmail, sameAs: [ SITE.autorLinkedin, SITE.repositorio, SITE.blog, ], }, }; }, };