feat(seo): og:locale pt_BR em todas as paginas, titulos e descricoes mais curtos, Person com cargo e areas; remove alegacao de LCP do SC Plus

- openGraph.locale pt_BR nas 6 rotas que redefinem openGraph (so a home tinha)
- titulos: cases usam 'Case de Engenharia'; /curriculo, Tauri e Engenharia de Software mais curtos; descricao da home (193 -> 146) e de AS Servicos (184 -> 136)
- Person JSON-LD ganha jobTitle e knowsAbout (dados e texto ja visiveis no site)
- SC Plus: remove 'otimizada para Core Web Vitals' / LCP < 2,5 s; Lighthouse mobile local mediu LCP 3,7 s. Texto passa a afirmar so metadados e dados estruturados (verificados no site)

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
Evandro Fonseca JuniorandClaude Sonnet 5.5 committed 2026-10-05 00:02:35 -03:00
1 parent 7c03dece9b
commit 85dd326964
12 files changed
+56 -27

No files matched your search

+2 -1
View File
@@ -35,10 +35,11 @@ export async function generateMetadata({
const url = `${siteUrl}/cases/${caseStudy.id}`;
return {
title: `${caseStudy.title} | Case de Engenharia de Software`,
title: `${caseStudy.title} | Case de Engenharia`,
description: caseStudy.summary,
alternates: { canonical: url },
openGraph: {
locale: "pt_BR",
title: caseStudy.title,
description: caseStudy.summary,
url,
+1
View File
@@ -18,6 +18,7 @@ export const metadata: Metadata = {
canonical: pageUrl,
},
openGraph: {
locale: "pt_BR",
title: pageTitle,
description: pageDescription,
url: pageUrl,
+2 -1
View File
@@ -8,11 +8,12 @@ import { siteName, siteUrl } from "@/lib/site-content";
const pageUrl = `${siteUrl}/curriculo`;
export const metadata: Metadata = {
title: "Currículo de Evandro Fonseca Junior para Contratação",
title: { absolute: `Currículo de Evandro Fonseca Junior | ${siteName}` },
description:
"Currículo profissional de Evandro Fonseca Junior, engenheiro da computação e desenvolvedor de software, com experiência, formação e competências técnicas.",
alternates: { canonical: pageUrl },
openGraph: {
locale: "pt_BR",
title: `Currículo de Evandro Fonseca Junior | ${siteName}`,
description:
"Experiência profissional, formação e competências técnicas de Evandro Fonseca Junior para avaliação de contratação.",
+1 -1
View File
@@ -12,7 +12,7 @@ import "./globals.css";
const defaultTitle = "Sistemas sob medida para empresas | Evandro.dev.br";
const seoDescription =
"Desenvolvimento de sistemas web, aplicativos e integrações sob medida. Do entendimento do negócio à entrega em produção, com Evandro Fonseca Junior. Base em Santa Catarina e atendimento remoto.";
"Sistemas web, aplicativos e integrações sob medida, do negócio à produção, com Evandro Fonseca Junior. Base em Santa Catarina, atendimento remoto.";
const spaceGrotesk = Space_Grotesk({
subsets: ["latin"],
+1
View File
@@ -12,6 +12,7 @@ export const metadata: Metadata = {
"Como o portfólio trata dados de contato, consentimento de analytics, links externos e solicitações de privacidade.",
alternates: { canonical: pageUrl },
openGraph: {
locale: "pt_BR",
title: `Privacidade e consentimento | ${siteName}`,
description:
"Informações factuais sobre contato, analytics e preferências de privacidade no portfólio.",
+1
View File
@@ -45,6 +45,7 @@ export async function generateMetadata({
canonical: url,
},
openGraph: {
locale: "pt_BR",
title: service.seoTitle,
description: service.metaDescription,
url,
+1
View File
@@ -56,6 +56,7 @@ export const metadata: Metadata = {
canonical: pageUrl,
},
openGraph: {
locale: "pt_BR",
title: pageTitle,
description: pageDescription,
url: pageUrl,
+7
View File
@@ -100,6 +100,13 @@ describe("factual portfolio records", () => {
);
});
it("does not claim measured performance for SC Plus without a stored measurement", () => {
// Lighthouse mobile local: LCP 3,7 s em 2026-10-05; a alegação anterior (LCP < 2,5 s) não se sustentava
expect(serializeProject("sc-plus")).not.toMatch(
/LCP|Core Web Vitals|otimizad|velocidade|rápid|Performance/i,
);
});
it("does not publish the unavailable Twins Lab demo", () => {
expect(
portfolio.projects.find((item) => item.id === "twins-lab")?.demoUrl,
+12 -1
View File
@@ -37,7 +37,17 @@ it("keeps the root graph limited to verified website and person fields", () => {
["@id", "@type", "inLanguage", "name", "publisher", "url"].sort(),
);
expect(Object.keys(person).sort()).toEqual(
["@id", "@type", "homeLocation", "image", "name", "sameAs", "url"].sort(),
[
"@id",
"@type",
"homeLocation",
"image",
"jobTitle",
"knowsAbout",
"name",
"sameAs",
"url",
].sort(),
);
expect(website).toMatchObject({
"@type": "WebSite",
@@ -49,6 +59,7 @@ it("keeps the root graph limited to verified website and person fields", () => {
"@type": "Person",
"@id": SEO_IDS.person,
image: `${siteUrl}/edev.jpg`,
jobTitle: "Engenheiro da Computação e Desenvolvedor de Software",
homeLocation: { "@type": "Place", name: "Garuva, Santa Catarina, Brasil" },
sameAs: [
"https://github.com/evandrodevbr",
+12
View File
@@ -24,6 +24,18 @@ export function buildPersonJsonLd() {
name: "Evandro Fonseca Junior",
url: siteUrl,
image: `${siteUrl}/edev.jpg`,
// cargo e áreas vêm de public/portfolio-data.json e estão visíveis em /curriculo e na seção de skills
jobTitle: "Engenheiro da Computação e Desenvolvedor de Software",
knowsAbout: [
"Next.js",
"React",
"TypeScript",
"Node.js",
"Python",
"IoT",
"Computação em nuvem",
"Inteligência artificial",
],
homeLocation: {
"@type": "Place",
name: "Garuva, Santa Catarina, Brasil",
+7 -7
View File
@@ -146,7 +146,7 @@ export const servicePages: ServicePageContent[] = [
slug: "engenharia-de-software",
navLabel: "Sistemas web e aplicativos mobile",
eyebrow: "Engenharia de software",
seoTitle: "Desenvolvimento de Sistemas Web e Aplicativos Mobile",
seoTitle: "Sistemas Web e Aplicativos Mobile sob Medida",
metaDescription:
"Sistemas web e aplicativos mobile sob medida, integração entre ferramentas e evolução de software existente. Escopo, plataformas e entregas definidos por projeto.",
headline: "Sistemas e apps para o seu trabalho.",
@@ -268,7 +268,7 @@ export const servicePages: ServicePageContent[] = [
slug: "tauri-rust",
navLabel: "Aplicativos desktop para Windows e Linux",
eyebrow: "Aplicativos desktop",
seoTitle: "Aplicativos Desktop para Windows e Linux com Tauri e Rust",
seoTitle: "Aplicativos Desktop com Tauri e Rust",
metaDescription:
"Desenvolvimento de aplicativos desktop para Windows e Linux com Tauri e Rust. Ferramentas locais, arquivos e integrações com compatibilidade definida por projeto.",
headline: "Aplicativos para Windows e Linux.",
@@ -692,11 +692,11 @@ export const caseStudies: CaseStudyContent[] = [
{
id: "sc-plus",
title: "SC Plus Aquicultura",
subtitle: "Site institucional em Next.js com foco em performance e SEO",
subtitle: "Landing page institucional em Next.js 15",
summary:
"Landing page em Next.js 15 otimizada para Core Web Vitals, metadata e estrutura técnica de indexação.",
"Landing page institucional em Next.js 15, React 19 e Tailwind CSS 4, com metadados e dados estruturados para indexação.",
impact:
"Exemplo de projeto em que clareza de mensagem, velocidade e SEO técnico trabalham juntos.",
"Dar à instituição uma página própria, com base técnica para ser encontrada em buscadores.",
stack: ["Next.js 15", "React 19", "Tailwind CSS 4", "TypeScript"],
demoUrl: "https://scplus.evandro.dev.br",
githubUrl: "https://github.com/evandrodevbr/scplus",
@@ -768,7 +768,7 @@ export const caseStudies: CaseStudyContent[] = [
title: "AS Serviços",
subtitle: "Site institucional com cena 3D procedural",
summary:
"Site institucional em Next.js 16 que representa quatro frentes de engenharia com uma cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
"Site institucional em Next.js 16 com cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
impact:
"Representar engenharia física e software na mesma narrativa visual sem depender de um modelo 3D pronto.",
stack: ["Next.js 16", "Three.js", "TypeScript"],
@@ -777,7 +777,7 @@ export const caseStudies: CaseStudyContent[] = [
role: "Desenvolvimento da primeira landing page do site, com animações 3D, e de um painel para controle de projetos.",
detail: {
answer: {
text: "Site institucional em Next.js 16 que representa quatro frentes de engenharia com uma cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
text: "Site institucional em Next.js 16 com cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
sourceIds: ["as-readme", "as-package", "as-engine"],
},
challenge: {
+9 -16
View File
@@ -178,28 +178,21 @@
{
"id": "sc-plus",
"title": "SC Plus Aquicultura",
"subtitle": "Landing Page Institucional",
"description": "Landing page Next.js 15 com React 19 e Tailwind CSS 4. Arquitetura otimizada para Core Web Vitals com LCP < 2.5s através de code splitting e server-side rendering. SEO técnico implementado com meta tags dinâmicas e structured data.",
"longDescription": "Site institucional responsivo desenvolvido com as mais recentes tecnologias web, otimizado para performance e SEO, apresentando os serviços e valores da empresa de aquicultura sustentável.",
"technologies": [
"Next.js 15",
"React 19",
"Tailwind CSS 4",
"TypeScript"
],
"subtitle": "Landing page institucional em Next.js 15",
"description": "Landing page institucional em Next.js 15, React 19 e Tailwind CSS 4, com metadados e dados estruturados para indexação.",
"longDescription": "Site institucional em Next.js 15 com React 19 e Tailwind CSS 4. A página publica título, descrição, URL canônica, imagem social e dados estruturados.",
"technologies": ["Next.js 15", "React 19", "Tailwind CSS 4", "TypeScript"],
"features": [
"Design moderno e responsivo",
"Performance otimizada",
"SEO otimizado",
"Interface intuitiva",
"Carregamento rápido"
"Landing page institucional",
"Metadados e URL canônica",
"Dados estruturados"
],
"category": "web",
"level": "pleno",
"status": "Concluído",
"demoUrl": "https://scplus.evandro.dev.br",
"githubUrl": "https://github.com/evandrodevbr/scplus",
"badges": ["Responsive", "SEO", "Modern Stack"],
"badges": ["Landing page", "Next.js 15"],
"featured": true,
"metrics": {
"complexity": 2,
@@ -236,7 +229,7 @@
"id": "as-servicos",
"title": "AS Serviços",
"subtitle": "Site Institucional com Cena 3D Procedural",
"description": "Site institucional em Next.js 16 que representa quatro frentes de engenharia com uma cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
"description": "Site institucional em Next.js 16 com cena Three.js gerada em código: uma casa wireframe e uma placa-mãe ligadas ao progresso da rolagem.",
"longDescription": "O motor monta casa, instalação elétrica e placa-mãe com geometrias e linhas do Three.js. O canvas converte a rolagem em progresso de 0 a 1, e a qualidade se adapta conforme WebGL, reduced motion, economia de dados, conexão e capacidade do dispositivo.",
"technologies": ["Next.js 16", "TypeScript", "Three.js"],
"features": [