Most SEO advice is written for marketers. This is the developer version: a spec you can implement, verify, and ship.
Metadata is an API, not an afterthought
Next.js gives you a typed Metadata API. Use it dynamically — every page should describe itself:
export async function generateMetadata({ params }): Promise<Metadata> {
const { slug } = await params;
const post = getPost(slug);
return {
title: post.title,
description: post.description,
alternates: { canonical: `/blog/${slug}` },
openGraph: {
type: "article",
publishedTime: post.date,
authors: [post.author],
},
};
}Set
metadataBaseonce in your root layout. Every relative URL in metadata resolves against it, and forgetting it is the #1 cause of broken OG images.
JSON-LD is how you talk to Google
Meta tags describe a page. Structured data describes entities. An article page should ship at minimum:
| Schema | Purpose |
|---|---|
Article |
Headline, author, dates, image for rich results |
BreadcrumbList |
The breadcrumb trail shown in search results |
Person |
Author identity, linked across your site |
Organization |
Publisher identity and logo |
Render it as a script tag from the server — no client JavaScript needed:
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleSchema) }}
/>Canonicals prevent self-inflicted duplicate content
Every page needs exactly one canonical URL. Generate it — never hand-write it:
/blog/my-postand/blog/my-post/must resolve to one canonical- Pagination pages canonicalize to themselves, not to page one
- Syndicated content points its canonical back at your original
The crawl budget essentials
-
sitemap.xmlgenerated from your content source, never hand-maintained -
robots.txtthat blocks admin/API routes and links the sitemap - RSS feed — still the fastest way to get content discovered
-
404responses that are actually HTTP 404, not soft 200s
Speed is a ranking factor you control
Core Web Vitals are measured on real users. The developer levers, in order of impact:
- Static generation — TTFB you cannot beat
next/image— sized, lazy, modern formats- Zero unnecessary client JavaScript
- Font loading via
next/font— no layout shift, no FOIT
None of this is a growth hack. It is engineering hygiene that compounds for years.

