feat(cases): mídia no topo, títulos de busca curtos e CreativeWork

Case com mídia ao lado do título e play acessível; problema de cada cliente reescrito com base nos dados; serviços relacionados em 2 cards; FAQ antes do próximo passo e bloco 'Onde já apliquei isso'; Apolo citada em IoT e arquitetura. metaTitle até 43 caracteres e descrições até 155 com teste; JSON-LD CreativeWork; imagens de compartilhamento abaixo de 100 KB; 404 e robots corrigidos; server-only nos módulos com node:.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 14:15:25 -03:00
1 parent c9a0b80656
commit e80f73d075
52 files changed
+2593 -439

No files matched your search

+21 -20
View File
@@ -17,13 +17,12 @@ import {
labCases,
siteUrl,
} from "@/lib/site-content";
import { CaseCover } from "./_components/CaseCover";
import { getCaseMedia } from "./_components/case-media";
import { CaseCoverLink } from "./_components/CaseCoverLink";
const pageUrl = `${siteUrl}/cases`;
const pageTitle = "Cases: Sites e Sistemas Feitos para Empresas";
const pageTitle = "Cases: sites e sistemas para empresas";
const pageDescription =
"Veja o que já foi feito para empresas: loja virtual com pedido pelo WhatsApp, site com painel para o dono, páginas institucionais e mais. Confira cada projeto e converse sobre o seu.";
"Veja o que já foi feito para empresas: loja virtual com pedido pelo WhatsApp, site com painel para o dono e páginas institucionais.";
const allCases = [...clientCases, ...labCases];
export const metadata: Metadata = {
@@ -41,33 +40,34 @@ function CaseCard({
caseStudy,
withCover,
ctaLabel,
priority = false,
}: {
caseStudy: CaseStudyContent;
withCover: boolean;
ctaLabel: string;
/** Capa que abre a página (a primeira, o maior elemento visível): carrega antes das demais. */
priority?: boolean;
}) {
return (
<article className="ds-card !h-auto">
{withCover && getCaseMedia(caseStudy.id, "desktop") ? (
<Link
href={`/cases/${caseStudy.id}`}
aria-hidden="true"
tabIndex={-1}
className="mb-sp-5 block"
>
<CaseCover
id={caseStudy.id}
title={caseStudy.title}
demoUrl={caseStudy.demoUrl}
sizes="(min-width: 1024px) 560px, 100vw"
/>
</Link>
{withCover ? (
<CaseCoverLink
id={caseStudy.id}
title={caseStudy.title}
demoUrl={caseStudy.demoUrl}
priority={priority}
prefetch={false}
/>
) : null}
<div className="ds-kicker">{caseStudy.title}</div>
<h3 className="ds-card-title">{caseStudy.headline}</h3>
<p className="ds-copy">{caseStudy.summary}</p>
<div className="mt-sp-6 flex flex-wrap items-center gap-sp-3">
<Link href={`/cases/${caseStudy.id}`} className={secondaryButtonLight}>
<Link
href={`/cases/${caseStudy.id}`}
prefetch={false}
className={secondaryButtonLight}
>
{ctaLabel}
</Link>
{caseStudy.demoUrl ? (
@@ -142,12 +142,13 @@ export default function CasesPage() {
Projetos de clientes
</h2>
<div className="ds-grid-2 mt-sp-8 items-start">
{clientCases.map((caseStudy) => (
{clientCases.map((caseStudy, index) => (
<CaseCard
key={caseStudy.id}
caseStudy={caseStudy}
withCover
ctaLabel="Ver o case"
priority={index === 0}
/>
))}
</div>