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:.
74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
import { notFound } from "next/navigation";
|
|
import { ImageResponse } from "next/og";
|
|
import {
|
|
OG_CONTENT_TYPE,
|
|
OG_PHOTO_CONTENT_TYPE,
|
|
OG_SIZE,
|
|
OgCard,
|
|
readProjectOgImage,
|
|
} from "@/lib/og-card";
|
|
import { caseStudies, isClientCase } from "@/lib/site-content";
|
|
|
|
function getCaseStudy(slug: string) {
|
|
return caseStudies.find(({ id }) => id === slug);
|
|
}
|
|
|
|
// Quem tem a capa gravada (public/videos/<id>/og.jpg, abaixo de 150 KB) a entrega como está, em JPEG: o cartão em PNG com a capa de fundo passava de 270 KB.
|
|
function getImageMetadata(caseStudy: (typeof caseStudies)[number]) {
|
|
return {
|
|
id: caseStudy.id,
|
|
alt: `Case ${caseStudy.title} — Evandro Fonseca Junior`,
|
|
size: OG_SIZE,
|
|
contentType: readProjectOgImage(caseStudy.id)
|
|
? OG_PHOTO_CONTENT_TYPE
|
|
: OG_CONTENT_TYPE,
|
|
};
|
|
}
|
|
|
|
export function generateImageMetadata({
|
|
params,
|
|
}: {
|
|
params: { slug?: string };
|
|
}) {
|
|
if (!params.slug) {
|
|
return caseStudies.map(getImageMetadata);
|
|
}
|
|
|
|
const caseStudy = getCaseStudy(params.slug);
|
|
if (!caseStudy) notFound();
|
|
return [getImageMetadata(caseStudy)];
|
|
}
|
|
|
|
export default async function Image({
|
|
params,
|
|
id,
|
|
}: {
|
|
params: Promise<{ slug: string }>;
|
|
id: Promise<string>;
|
|
}) {
|
|
const [{ slug }, imageId] = await Promise.all([params, id]);
|
|
const caseStudy = getCaseStudy(slug);
|
|
if (!caseStudy || imageId !== caseStudy.id) notFound();
|
|
|
|
const photo = readProjectOgImage(caseStudy.id);
|
|
if (photo) {
|
|
return new Response(new Uint8Array(photo), {
|
|
headers: {
|
|
"Content-Type": OG_PHOTO_CONTENT_TYPE,
|
|
"Cache-Control": "public, max-age=86400",
|
|
},
|
|
});
|
|
}
|
|
|
|
return new ImageResponse(
|
|
<OgCard
|
|
eyebrow={
|
|
isClientCase(caseStudy) ? "Case de cliente" : "Projeto de laboratório"
|
|
}
|
|
title={caseStudy.title}
|
|
description={caseStudy.summary}
|
|
/>,
|
|
OG_SIZE,
|
|
);
|
|
}
|