Metadata comes from data, never from strings
The App Router's generateMetadata runs on the server with the same params the page uses, so the title, description and canonical can be derived from the record the page is about. A hand-written title in a page file is a second copy of a fact, and second copies drift.
One canonical per language
The Arabic page and the English page are not duplicates of each other — they are alternates. Each one canonicalises to itself. Pointing the Arabic page's canonical at the English URL, which happens constantly, tells a search engine that the Arabic version should not be indexed at all.
hreflang has to be reciprocal
- Every page lists every language version of itself, including its own.
- The declarations must agree in both directions — if A names B, B must name A.
- Use absolute URLs. A relative alternate is ignored.
- Include an x-default pointing at the version a visitor with no language match should get.
- Never generate alternates for a page that does not exist in that language.
The sitemap is generated, not maintained
Build it from the same arrays that produce the routes, so a new case study appears in the sitemap the moment it exists and an unpublished draft never does. Include lastModified from the record's own date rather than the build time — a sitemap where every URL changed today says nothing.
robots.txt, and what you are deciding
Disallowing a path does not remove it from an index — it prevents crawling, which can leave a URL indexed with no description. Use noindex for pages that should not appear, and robots.txt for paths that should not be fetched. They are different tools and using one for the other's job is the most common technical SEO mistake there is.
Before a Next.js site ships
- View source on three routes: is the content in the HTML, or only after hydration?
- One self-referencing canonical per page, absolute, matching the served URL exactly.
- Reciprocal hreflang across both languages, plus x-default.
- One JSON-LD @graph per page with stable @id values shared across the site.
- sitemap.xml generated from route data, with honest lastModified values.
- robots.txt allows the crawlers you intend — check the AI user agents explicitly.
- A 404 that returns 404, and a redirect map for every URL that ever changed.
- OpenGraph images that exist and resolve absolutely.
Sources
Related services
Related work
Read next
- Technical SEOStructured data, written as a graph instead of a pileHow should structured data be organised so a machine can tell the entities apart?
- AI SearchHow to build a site an AI assistant can actually citeWhat makes a web page citable by an AI assistant?
- WordPressThe order a web project has to be built in, and what deferring costsWhat order should a web project actually be built in?
