How to Add Canonical Tags to Next.js for SEO
Canonical tags are an essential feature on websites for SEO reasons.
What Are Canonical Tags and Why Are They Important?
Google says:
If you have a single page that’s accessible by multiple URLs, or different pages with similar content (for example, a page with both a mobile and a desktop version), Google sees these as duplicate versions of the same page. Google will choose one URL as the canonical version and crawl that, and all other URLs will be considered duplicate URLs and crawled less often.
If you don’t explicitly tell Google which URL is canonical, Google will make the choice for you, or might consider them both of equal weight, which might lead to unwanted behavior…
Canonical tags are the way that you tell Google and other search engines which URL is the correct one.
Canonical tags go in the <head> section of your HTML, and they contain the full URL of the current page. Here’s an example of a canonical tag for the home page of the URL https://example.com/:
<link rel="canonical" href="https://example.com/" />
If there were a path on that site at /about/, the canonical tag on that page would look like this:
<link rel="canonical" href="https://example.com/about/" />
Imagine that you had a campaign URL tracking how many visits came to your page at https://example.com/winter-sale/ via a specific newsletter. The URL that visitors land on might look something like this:
https://example.com/winter-sale/?utm_source=newsletter&utm_medium=email&utm_campaign=winter_sale&utm_id=123
That page still shows the content of https://example.com/winter-sale/ but it has a different URL, which can confuse search engines.
Adding a canonical tag to every page with the correct URL is the way to let Google and other search engines know that the pages are the same and which URL is the correct, or canonical, one.
Implement Canonical Tags in Next.js
Canonical tags can be added to Next.js sites in the _app.js (or _app.tsx if you’re using TypeScript). I’ll put examples of both below.
JavaScript Version
import { useRouter } from "next/router";
import Head from "next/head";
// I'm using MDX here, but you can omit all the lines with "MDX" if you aren't
// using MDX.
import MDX from "../components/mdx";
export default function MyApp({ Component, pageProps }) {
const router = useRouter();
const p = router.asPath.slice(1);
const canonicalURL = `https://example.com${p}`.split("?")[0];
return (
<>
<Head>
<link rel="canonical" href={canonicalURL} />
</Head>
<MDX>
<Component {...pageProps} />
</MDX>
</>
);
}
TypeScript Version
import type { AppProps } from "next/app";
import { useRouter } from "next/router";
import Head from "next/head";
// I'm using MDX here, but you can omit all the lines with "MDX" if you aren't
// using MDX.
import MDX from "../components/mdx";
export default function MyApp({ Component, pageProps }: AppProps) {
const router = useRouter();
const p = router.asPath.slice(1);
const canonicalURL = `https://example.com${p}`.split("?")[0];
return (
<>
<Head>
<link rel="canonical" href={canonicalURL} />
</Head>
<MDX>
<Component {...pageProps} />
</MDX>
</>
);
}
I got the idea from this post.
For more information about canonical tags, see Google’s documentation page.
If you have questions, leave a comment below.