eduardweb.
DeploymentIntermediar#seo#nextjs#typescript#react

Metadata API în Next.js 16: generateMetadata dinamic, OG Images și JSON-LD curat

De Bogdan Răducanu, 22 iul. 2026 · 15 vizualizări · 3 like-uri

Postat 22 iul. 2026
typescript
import { Metadata, ResolvingMetadata } from 'next';
import { cache } from 'react';

// Deduping manual pentru ORM-uri (Prisma/Drizzle)
const getProduct = cache(async (id: string) => {
  return await db.product.findUnique({ where: { id } });
});

type Props = { params: Promise<{ id: string }> };

export async function generateMetadata(
  { params }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  const { id } = await params;
  const product = await getProduct(id);
  const parentImages = (await parent).openGraph?.images || [];

  return {
    title: product?.name,
    description: product?.summary,
    openGraph: {
      title: product?.name,
      images: [`/api/og?title=${encodeURIComponent(product?.name || '')}`, ...parentImages],
    },
  };
}

Am refăcut recent arhitectura de SEO pentru o platformă SaaS cu peste 35.000 de pagini dinamice, trecând complet pe Next.js 16. Dacă încă mai folosești hack-uri vechi, componente de client pentru head sau pachete gen react-helmet, pierzi masiv la capitolul viteza de indexare. Metadata API-ul nativ din App Router rezolvă problema asta curat, dar vine la pachet cu niște capcane subtile de performanță dacă nu înțelegi cum funcționează rezolvarea asincronă.

Cum funcționează generateMetadata fără să îți îngroape baza de date

Cea mai mare greșeală pe care o văd în audituri este dublarea query-urilor către backend. Devii apelează baza de date o dată în generateMetadata pentru titlu și descriere, și încă o dată în Server Component-ul paginii pentru a randa UI-ul.

Dacă folosești fetch()-ul nativ extins de Next.js, framework-ul face deduping automat pentru exact aceleași endpoint-uri și parametri. Problema apare când folosești un ORM (Prisma, Drizzle) sau un SDK de bază de date. Acolo fetch nu este interceptat. Am avut cazul la un client unde serverul făcea 80 de query-uri pe secundă doar pentru meta tag-uri pe o pagină de categorie. Soluția e simplă: împachetezi apelul de date într-o funcție wrapped cu cache() din pachetul nativ react.

Un alt detaliu util în Next 16 este parametrul parent. Poți să aștepți parent metadata (de exemplu imaginile OG setate în layout.tsx) și doar să adaugi sau să suprascrii ce ai nevoie în pagina copil, fără să re-construiești tot obiectul.

OG Images dinamice: Flexbox limitat vs CTR crescut

Pentru paginile de produs sau postările de blog, generarea dinamică de OG Images cu ImageResponse din next/og schimbă jocul. În loc să ai o imagine generică cu logo-ul firmei, poți randa dinamic titlul articolului, autorul și o imagine de fundal direct în format PNG, pe Edge.

Trade-off-ul sincer? Runtime-ul care randează JSX în SVG/PNG folosește un engine restrâns (Satori). Asta înseamnă că nu ai suport complet de CSS. Fără layout-uri ultra-complexe, fără animații, iar fonturile personalizate trebuie încărcate ca ArrayBuffer. În plus, generarea pe server consumă CPU. Pentru un site cu spike-uri mari, este esențial să pui un header agresiv de caching (Cache-Control: public, max-age=31536000, immutable) sau să folosești un CDN în față. Totuși, efortul merită: la noi, OG-urile dinamice au crescut CTR-ul din social media cu 22%.

Structured Data (JSON-LD) fără pachete npm inutile

Să instalezi o bibliotecă terță doar ca să pui un JSON-LD de Schema.org în pagină este o risipă de resurse. În Next.js App Router, injectarea de date structurate se face banal, direct în Server Component, printr-un tag de <script>.

Nu ai nevoie de hydrate pe client pentru asta, crawlerii Google citesc HTML-ul brut generat pe server. Practic, scoți cod din bundle-ul de JS care ajunge la browser.

Voi cum gestionați SEO-ul pe proiectele mari de Next.js? Ați trecut complet pe App Router sau încă aveți bucăți rămase pe Pages Router din cauza legacy code-ului?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.