Discoverability · Next.js (App Router)
How to set canonical URLs correctly in Next.js (App Router)
A canonical tag pointing at the wrong target tells search engines to index that page instead of this one — every page pointing at the homepage removes your whole site from search except one URL, while everything still looks correct in a browser. With no canonical at all, the same page reached through a tracking parameter, a trailing slash or the www host can be treated as several competing pages.
The fix for Next.js (App Router)
13x detects your framework from the response and hands you this version rather than the generic one — below 50% confidence it hedges and gives you the generic one instead.
Set metadataBase once in the root layout, then a relative canonical per page. Next resolves them together:
// app/layout.tsx
export const metadata: Metadata = {
metadataBase: new URL("https://example.com"),
};
// app/pricing/page.tsx
export const metadata: Metadata = {
alternates: { canonical: "/pricing" },
};For dynamic routes, use generateMetadata:
export async function generateMetadata({ params }): Promise<Metadata> {
const { slug } = await params;
return { alternates: { canonical: `/blog/${slug}` } };
}Note that params is a Promise in current Next versions.
On a different stack? The general version of this fix explains what 13x checks and why it matters, without assuming a framework.
Check your Next.js (App Router) site
113 deterministic checks against your live URL, in about 30 seconds. Framework detected from the response, so every fix comes back in the form your stack actually uses.
No signup. Results in 30 seconds.