Skip to content

Canonical tag missing

Without a canonical tag, Google decides which version of your URL to index on its own. It might pick the www variant, a query-string copy, or a path with a trailing slash. The canonical tag is how you declare which URL is authoritative. Missing it means you are relying on Google’s guess.

Add an absolute rel="canonical" link to every public page pointing to its preferred URL.

Use the static metadata export for fixed pages, or generateMetadata for dynamic ones:

app/page.tsx
export const metadata = {
alternates: {
canonical: 'https://yourdomain.com',
},
}
app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: { params: { slug: string } }) {
return {
alternates: {
canonical: `https://yourdomain.com/blog/${params.slug}`,
},
}
}

Use next/head inside each page component:

import Head from 'next/head'
export default function AboutPage() {
return (
<>
<Head>
<link rel="canonical" href="https://yourdomain.com/about" />
</Head>
</>
)
}

Use <svelte:head> in each page or layout:

src/routes/about/+page.svelte
<svelte:head>
<link rel="canonical" href="https://yourdomain.com/about" />
</svelte:head>

For dynamic pages, use $page.url.href:

<script>
import { page } from '$app/stores'
</script>
<svelte:head>
<link rel="canonical" href={$page.url.href} />
</svelte:head>

Call useHead in your page or layout component:

pages/about.vue
useHead({
link: [
{ rel: 'canonical', href: 'https://yourdomain.com/about' },
],
})

For dynamic pages, use useRequestURL:

pages/blog/[slug].vue
const url = useRequestURL()
useHead({
link: [
{ rel: 'canonical', href: url.href },
],
})

Pass the canonical URL through your base layout:

src/layouts/Layout.astro
---
const { canonical } = Astro.props
---
<head>
<link rel="canonical" href={canonical} />
</head>
src/pages/about.astro
---
import Layout from '../layouts/Layout.astro'
---
<Layout canonical="https://yourdomain.com/about">
<!-- page content -->
</Layout>

Check that the canonical appears in the rendered HTML:

Terminal window
curl -s https://yourdomain.com/ | grep canonical

Expected output:

<link rel="canonical" href="https://yourdomain.com/" />

Re-run orino audit to confirm the check passes.