CI / Lint e auditorias (push) Successful in 1m10s
CI / Trivy (dependências e segredos) (push) Successful in 12s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m39s
Release / Plano (reaproveitar a imagem?) (push) Successful in 6s
Release / ci (push) Skipped
Release / Publica a imagem (linux/arm64) (push) Successful in 18s
Release / Cria a release no Gitea (push) Successful in 5s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
494 lines
18 KiB
JavaScript
494 lines
18 KiB
JavaScript
/**
|
|
* 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.
|
|
*/
|
|
|
|
import { ENABLED_LOCALES, getLocalizedHref } from "@/i18n/links";
|
|
|
|
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://git.lucasrguerra.dev.br/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", locale = "pt" }) {
|
|
const currentLocale = locale || "pt";
|
|
const basePath = caminho.startsWith("/") ? caminho : `/${caminho}`;
|
|
const canonicalPath = getLocalizedHref(`/pt${basePath}`, currentLocale);
|
|
const url = `${SITE.url}${canonicalPath}`;
|
|
|
|
const languages = {};
|
|
for (const loc of ENABLED_LOCALES) {
|
|
if (basePath === "/livro" && loc !== "pt") continue;
|
|
const locHref = getLocalizedHref(`/pt${basePath}`, loc);
|
|
const langKey = loc === "pt" ? "pt-BR" : loc === "es" ? "es-419" : loc;
|
|
languages[langKey] = `${SITE.url}${locHref}`;
|
|
}
|
|
if (ENABLED_LOCALES.includes("en") && basePath !== "/livro") {
|
|
languages["x-default"] = `${SITE.url}${getLocalizedHref(`/pt${basePath}`, "en")}`;
|
|
}
|
|
|
|
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 !== currentLocale && (basePath !== "/livro" || l === "pt"))
|
|
.map((l) => ogLocaleMap[l])
|
|
.filter(Boolean);
|
|
|
|
return {
|
|
title: titulo,
|
|
description: descricao,
|
|
keywords,
|
|
alternates: {
|
|
canonical: canonicalPath,
|
|
languages: Object.keys(languages).length > 1 ? languages : undefined,
|
|
},
|
|
openGraph: {
|
|
type: tipo,
|
|
locale: ogLocaleMap[currentLocale] || "pt_BR",
|
|
alternateLocale: alternateLocales.length > 0 ? alternateLocales : undefined,
|
|
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(locale = "pt") {
|
|
const isEn = locale === "en";
|
|
const isEs = locale === "es";
|
|
const isFr = locale === "fr";
|
|
const isDe = locale === "de";
|
|
const isZh = locale === "zh-CN";
|
|
const orgAnchor = isZh ? "organization" : isEn ? "organization" : isEs ? "organizacion" : (isFr || isDe) ? "organisation" : "organizacao";
|
|
const authorAnchor = isEn ? "author" : isFr ? "auteur" : "autor";
|
|
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
|
|
return {
|
|
"@context": "https://schema.org",
|
|
"@graph": [
|
|
{
|
|
"@type": "WebSite",
|
|
"@id": `${SITE.url}/#site`,
|
|
url: `${SITE.url}/${locale}`,
|
|
name: SITE.nome,
|
|
inLanguage: inLang,
|
|
description: isEn
|
|
? "ESP32 ecosystem documentation: specifications, pinouts, comparison, and series selection."
|
|
: isEs
|
|
? "Documentación del ecosistema ESP32: especificaciones, patillaje, comparación y selección de series."
|
|
: isFr
|
|
? "Documentation de l'écosystème ESP32 : spécifications, brochages, comparaison et sélection de séries."
|
|
: isZh ? "ESP32 生态文档(简体中文):规格、引脚、对比与系列选型。" : isDe
|
|
? "Dokumentation des ESP32-Ökosystems: Spezifikationen, Pinbelegung, Vergleich und Serienauswahl."
|
|
: "Documentação do ecossistema ESP32 em português brasileiro: especificações, pinagem, comparação e seleção de séries.",
|
|
publisher: { "@id": `${SITE.url}/#${orgAnchor}` },
|
|
},
|
|
{
|
|
"@type": "Organization",
|
|
"@id": `${SITE.url}/#${orgAnchor}`,
|
|
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}/#${authorAnchor}`,
|
|
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, locale = "pt") {
|
|
const isEn = locale === "en";
|
|
const isEs = locale === "es";
|
|
const isFr = locale === "fr";
|
|
const isDe = locale === "de";
|
|
const isZh = locale === "zh-CN";
|
|
const prop = (nome, valor) =>
|
|
valor ? { "@type": "PropertyValue", name: nome, value: String(valor) } : null;
|
|
|
|
const propriedades = [
|
|
prop(isEn ? "Manufacturer" : isEs ? "Fabricante" : isFr ? "Fabricant" : isZh ? "制造商" : isDe ? "Hersteller" : "Fabricante", "Espressif Systems"),
|
|
prop(isEn ? "Architecture" : isEs ? "Arquitectura" : isFr ? "Architecture" : isZh ? "架构" : isDe ? "Architektur" : "Arquitetura"),
|
|
prop(isEn ? "Cores" : isEs ? "Núcleos" : isFr ? "Cœurs" : isZh ? "内核数" : isDe ? "Kerne" : "Núcleos", serie.nucleos),
|
|
prop(isEn ? "Max frequency" : isEs ? "Frecuencia máxima" : isFr ? "Fréquence maximale" : isZh ? "最高频率" : isDe ? "Maximale Frequenz" : "Frequência máxima", serie.frequencia),
|
|
prop("SRAM", serie.memoria_sram),
|
|
prop("RTC SRAM", serie.memoria_sram_rtc),
|
|
prop(isEn ? "Supported Flash" : isEs ? "Flash soportada" : isFr ? "Flash prise en charge" : isZh ? "支持的闪存" : isDe ? "Unterstützter Flash" : "Flash suportada", serie.flash_suportada),
|
|
prop(isEn ? "Supported PSRAM" : isEs ? "PSRAM soportada" : isFr ? "PSRAM prise en charge" : isZh ? "支持的 PSRAM" : isDe ? "Unterstütztes PSRAM" : "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(isEn ? "Package" : isEs ? "Encapsulado" : isFr ? "Boîtier" : isZh ? "封装" : isDe ? "Gehäuse" : "Encapsulamento", serie.encapsulamento),
|
|
prop(isEn ? "Minimum ESP-IDF" : isEs ? "ESP-IDF mínimo" : isFr ? "ESP-IDF minimum" : isZh ? "最低 ESP-IDF 版本" : isDe ? "Mindestens ESP-IDF" : "ESP-IDF mínimo", serie.esp_idf_minimo),
|
|
].filter(Boolean);
|
|
|
|
const imagem = serie.placa
|
|
? `${SITE.url}${serie.placa}`
|
|
: `${SITE.url}/opengraph-image.png`;
|
|
|
|
const basePath = isZh ? `/zh-CN/series/${chave}` : isDe ? `/de/serien/${chave}` : isFr ? `/fr/series/${chave}` : isEn ? `/en/series/${chave}` : isEs ? `/es/series/${chave}` : `/series/${chave}`;
|
|
const anchor = isEn ? "article" : isEs ? "articulo" : isFr ? "article" : isZh ? "article" : isDe ? "artikel" : "artigo";
|
|
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
|
|
|
|
return {
|
|
"@context": "https://schema.org",
|
|
"@type": "TechArticle",
|
|
"@id": `${SITE.url}${basePath}#${anchor}`,
|
|
headline: isEn
|
|
? `${serie.nome_completo || chave}: specifications and pinout`
|
|
: isEs
|
|
? `${serie.nome_completo || chave}: especificaciones y patillaje`
|
|
: isFr
|
|
? `${serie.nome_completo || chave} : spécifications et brochage`
|
|
: isZh ? `${serie.nome_completo || chave}:规格与引脚图` : isDe
|
|
? `${serie.nome_completo || chave}: Spezifikationen und Pinbelegung`
|
|
: `${serie.nome_completo || chave}: especificações e pinagem`,
|
|
name: isEn
|
|
? `${serie.nome_completo || chave} - Technical Documentation and Specifications`
|
|
: isEs
|
|
? `${serie.nome_completo || chave} - Documentación técnica y especificaciones`
|
|
: isFr
|
|
? `${serie.nome_completo || chave} - Documentation technique et spécifications`
|
|
: isZh ? `${serie.nome_completo || chave} - 技术文档与规格` : isDe
|
|
? `${serie.nome_completo || chave} - Technische Dokumentation und Spezifikationen`
|
|
: `${serie.nome_completo || chave} - Documentação Técnica e Especificações`,
|
|
description: serie.descricao,
|
|
image: [imagem],
|
|
inLanguage: inLang,
|
|
datePublished: "2026-08-25T00:00:00.000Z",
|
|
dateModified: new Date().toISOString(),
|
|
mainEntityOfPage: `${SITE.url}${basePath}`,
|
|
url: `${SITE.url}${basePath}`,
|
|
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, locale = "pt") {
|
|
const isEn = locale === "en";
|
|
const isEs = locale === "es";
|
|
const isFr = locale === "fr";
|
|
const isDe = locale === "de";
|
|
const isZh = locale === "zh-CN";
|
|
const basePath = isZh ? `/zh-CN/frameworks/${encodeURIComponent(chave)}` : isDe ? `/de/frameworks/${encodeURIComponent(chave)}` : isFr ? `/fr/frameworks/${encodeURIComponent(chave)}` : isEn ? `/en/frameworks/${encodeURIComponent(chave)}` : isEs ? `/es/frameworks/${encodeURIComponent(chave)}` : `/frameworks/${encodeURIComponent(chave)}`;
|
|
const anchor = isEn ? "article" : isEs ? "articulo" : isFr ? "article" : isZh ? "article" : isDe ? "artikel" : "artigo";
|
|
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
|
|
return {
|
|
"@context": "https://schema.org",
|
|
"@type": "TechArticle",
|
|
"@id": `${SITE.url}${basePath}#${anchor}`,
|
|
headline: isEn
|
|
? `${framework.nome} for ESP32: Guide and Documentation`
|
|
: isEs
|
|
? `${framework.nome} para ESP32: Guía y documentación`
|
|
: isFr
|
|
? `${framework.nome} pour ESP32 : Guide et documentation`
|
|
: isZh ? `用于 ESP32 的 ${framework.nome}:指南与文档` : isDe
|
|
? `${framework.nome} für ESP32: Leitfaden und Dokumentation`
|
|
: `${framework.nome} para ESP32: Guia e Documentação`,
|
|
name: isEn
|
|
? `${framework.nome_completo || framework.nome} for ESP32`
|
|
: isFr
|
|
? `${framework.nome_completo || framework.nome} pour ESP32`
|
|
: isZh ? `用于 ESP32 的 ${framework.nome_completo || framework.nome}` : isDe
|
|
? `${framework.nome_completo || framework.nome} für ESP32`
|
|
: `${framework.nome_completo || framework.nome} para ESP32`,
|
|
description: framework.descricao,
|
|
image: [`${SITE.url}/opengraph-image.png`],
|
|
inLanguage: inLang,
|
|
datePublished: "2026-08-25T00:00:00.000Z",
|
|
dateModified: new Date().toISOString(),
|
|
mainEntityOfPage: `${SITE.url}${basePath}`,
|
|
url: `${SITE.url}${basePath}`,
|
|
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}${basePath}`,
|
|
},
|
|
};
|
|
},
|
|
|
|
/** Glossário: marca cada verbete como termo definido. */
|
|
glossario(categorias, locale = "pt") {
|
|
const isEn = locale === "en";
|
|
const isEs = locale === "es";
|
|
const isFr = locale === "fr";
|
|
const isDe = locale === "de";
|
|
const isZh = locale === "zh-CN";
|
|
const basePath = isZh ? "/zh-CN/glossary" : isDe ? "/de/glossar" : isFr ? "/fr/glossaire" : isEn ? "/en/glossary" : isEs ? "/es/glosario" : "/glossario";
|
|
const anchor = isZh ? "glossary" : isDe ? "glossar" : isFr ? "glossaire" : isEn ? "glossary" : isEs ? "glosario" : "glossario";
|
|
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
|
|
return {
|
|
"@context": "https://schema.org",
|
|
"@type": "DefinedTermSet",
|
|
"@id": `${SITE.url}${basePath}#${anchor}`,
|
|
name: isEn ? "ESP32 Technical Glossary" : isEs ? "Glosario técnico de ESP32" : isFr ? "Glossaire technique de l'ESP32" : isZh ? "ESP32 技术术语表" : isDe ? "Technisches Glossar für ESP32" : "Glossário Técnico do ESP32",
|
|
inLanguage: inLang,
|
|
hasDefinedTerm: categorias.flatMap((cat) =>
|
|
cat.termos.map((t) => ({
|
|
"@type": "DefinedTerm",
|
|
name: t.termo,
|
|
description: t.definicao,
|
|
inDefinedTermSet: `${SITE.url}${basePath}#${anchor}`,
|
|
}))
|
|
),
|
|
};
|
|
},
|
|
|
|
/** 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, locale = "pt" }) {
|
|
const isEn = locale === "en";
|
|
const isEs = locale === "es";
|
|
const isFr = locale === "fr";
|
|
const isDe = locale === "de";
|
|
const isZh = locale === "zh-CN";
|
|
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
|
|
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: inLang,
|
|
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(locale = "pt") {
|
|
const isEn = locale === "en";
|
|
const isEs = locale === "es";
|
|
const isFr = locale === "fr";
|
|
const isDe = locale === "de";
|
|
const isZh = locale === "zh-CN";
|
|
const basePath = isZh ? "/zh-CN/about" : isDe ? "/de/ueber-uns" : isFr ? "/fr/a-propos" : isEn ? "/en/about" : isEs ? "/es/acerca" : "/sobre";
|
|
const anchor = isZh ? "about" : isDe ? "ueber-uns" : isFr ? "a-propos" : isEn ? "about" : isEs ? "acerca" : "sobre";
|
|
const inLang = isEn ? "en" : isEs ? "es-419" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt-BR";
|
|
return {
|
|
"@context": "https://schema.org",
|
|
"@type": "AboutPage",
|
|
"@id": `${SITE.url}${basePath}#${anchor}`,
|
|
name: isEn ? "About ESPDocs" : isEs ? "Acerca de ESPDocs" : isFr ? "À propos d'ESPDocs" : isZh ? "关于 ESPDocs" : isDe ? "Über ESPDocs" : "Sobre o ESPDocs",
|
|
description: isEn
|
|
? "ESPDocs is an independent platform organizing technical documentation of the ESP32 ecosystem."
|
|
: isEs
|
|
? "ESPDocs es una plataforma independiente que reúne la documentación técnica del ecosistema ESP32."
|
|
: isFr
|
|
? "ESPDocs est une plateforme indépendante qui rassemble la documentation technique de l'écosystème ESP32."
|
|
: isZh ? "ESPDocs 是一个独立平台,汇集 ESP32 生态的文档,使用简体中文。" : isDe
|
|
? "ESPDocs ist eine unabhängige Plattform, die die technische Dokumentation des ESP32-Ökosystems zusammenführt."
|
|
: "O ESPDocs é uma plataforma independente que reúne a documentação do ecossistema ESP32 em português brasileiro.",
|
|
url: `${SITE.url}${basePath}`,
|
|
inLanguage: inLang,
|
|
mainEntity: {
|
|
"@type": "Person",
|
|
name: SITE.autor,
|
|
url: SITE.autorUrl,
|
|
email: SITE.autorEmail,
|
|
sameAs: [
|
|
SITE.autorLinkedin,
|
|
SITE.repositorio,
|
|
SITE.blog,
|
|
],
|
|
},
|
|
};
|
|
},
|
|
};
|