Canonical tag missing
What this means
Section titled “What this means”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.
How to fix it
Section titled “How to fix it”Add an absolute rel="canonical" link to every public page pointing to its preferred URL.
Next.js App Router
Section titled “Next.js App Router”Use the static metadata export for fixed pages, or generateMetadata for dynamic ones:
export const metadata = { alternates: { canonical: 'https://yourdomain.com', },}export async function generateMetadata({ params }: { params: { slug: string } }) { return { alternates: { canonical: `https://yourdomain.com/blog/${params.slug}`, }, }}Next.js Pages Router
Section titled “Next.js Pages Router”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> </> )}SvelteKit
Section titled “SvelteKit”Use <svelte:head> in each page or layout:
<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:
useHead({ link: [ { rel: 'canonical', href: 'https://yourdomain.com/about' }, ],})For dynamic pages, use useRequestURL:
const url = useRequestURL()useHead({ link: [ { rel: 'canonical', href: url.href }, ],})Pass the canonical URL through your base layout:
---const { canonical } = Astro.props---<head> <link rel="canonical" href={canonical} /></head>---import Layout from '../layouts/Layout.astro'---<Layout canonical="https://yourdomain.com/about"> <!-- page content --></Layout>Verify the fix
Section titled “Verify the fix”Check that the canonical appears in the rendered HTML:
curl -s https://yourdomain.com/ | grep canonicalExpected output:
<link rel="canonical" href="https://yourdomain.com/" />Re-run orino audit to confirm the check passes.