---
title: 'SEO for Devs: Own your work with canonical tags'
date: 2024-07-12
updated: 2026-06-23
excerpt: 'Canonical tags are a powerful tool to help search engines understand which version of a page is the original one. This can help you avoid duplicate content issues and ensure that your content gets the credit it deserves.'
tags: [seo, nextjs]
canonical: https://mikebifulco.com/posts/own-your-work-with-canonical-tags
---
# SEO for Devs: Own your work with canonical tags

> **TL;DR:** A canonical tag is a `<link rel="canonical" href="..." />` tag in your page `<head>` that tells search engines which URL is the original, authoritative home of the content. Use one when you cross-post to sites like Medium, Dev.to, or Hashnode so the original on your own site gets the SEO credit. In Next.js, add a single `<link>` via `next/head` (pages router) or the `alternates.canonical` field in `generateMetadata` (app router).

## Canonically Speaking: Own Your Work

You've gone through the trouble of planning, outlining, and writing an article - the product of hours (or sometimes days) of work. After publishing your work on your own site, you take the time to cross-post it on Hashnode, Medium, Dev.to, and Reddit, to get more eyes on it.

Great news: your work is a success! You're racking up likes and upvotes, and people are leaving thoughtful comments.

Some time later, you open up an incognito window, and do a Google search for your article, and it pops up!

...but wait, why is the top result Medium, and not `yourgreatwebsite.com`?

It sounds like it's time you learned about the `canonical` tag, its value for SEO, and why it matters if you're trying to build a brand for yourself, or for a product you're working on.

## What is a Canonical Tag?

The **canonical tag** is a specially formatted `<link />` tag in HTML which lets you specify the "canonical" or original version of the content on a given page. The Google crawler and other search engines use these in combination with a few other signals to determine which domain "owns" the content being shown.

In other words: **canonical tags tell search engines which URL should be considered the official home of whatever is on that page**.

### Syntax for the Canonical tag

Canonical tags go in the `<head>` section of an html page, and they look like this:

```html
<head>
  <!--
    you'll probably have a bunch of other stuff here,
    like title, stylesheet, and meta tags.
  -->
  <link rel="canonical" href="https://www.yoursite.com/some-article" />
</head>
```

**Important:** Your page should have *only one* canonical tag. Adding more than one can have negative or unintended effects on your search rankings!

### Some great reasons to use Canonical Tags

When your work is posted in multiple places online, canonical tags tells search crawlers which version should be considered the authoritative source.

If you cross post and don't use a canonical tag, it can lead to your poor search rankings *everywhere* for your work. This means that even if you get a boost initially from sharing on Hashnode, Medium, or Dev.to, it can actually *hurt* your chances to rank well in the long run.

In theory, this means that the signals search crawlers use to rank your articles (like backlinks and traffic statistics) should be attributed to the original source on your site. That's great news, because more backlinks and clicks through to your work *should* increase visibility on search engine results pages (SERPs).

### Another benefit: Protection Against Content Theft

Eventually, your high-traffic articles will copied and republished without your permission by spammy content aggregator sites looking to build traffic for themselves.

By having a canonical tag *on your site* from the start, and having it indexed by search engines, you ensure that these spam sites don't win by stealing your content. The canonical tag helps search engines recognize your original work and prioritize it in search results.

---

## Implementing Canonical Tags on your site

Thankfully, it's not particularly complicated to add canonical tags to your site. The long and short of it is that you need to add a `<link>` tag to the `<head>` section of your HTML pages, specifying the canonical URL of the content.

As an example here's a simple, step-by-step guide to implementing canonical tags in a Next.js site using the pages router:

### Create a New Next.js project

If you haven't already, you can create a new Next.js project by running the following commands in your terminal:

```bash
npx create-next-app@latest my-nextjs-site
cd my-nextjs-site
```

### Install the Next.js Head Component

Next.js provides a built-in `<Head />` component to help you manage the `<head>` section of your HTML. You don't need to install anything additional for this; it's already included with Next.js.

*A word of caution:* Using a `<Head />` tag on any page in your site gives you a way to add content to the `<head />` section rendered on the final page. This is super convenient, but that also makes it easy to unintentionally include more than one of these puppies per page -- and you don't want to do that.

### Add the Canonical Tag to Your Pages

Adding the tag to a single page is straightforward - toss it between `<Head>` tags, and make sure the `href` attribute has the *exact* same URL as this page will. **If your site pages have a trailing slash `example.com/hello/`, make sure to include it!**

```jsx
import Head from 'next/head';

export default function Home() {
  return (
    <div>
      <Head>
        <title>My Next.js Site</title>
        <link rel="canonical" href="https://www.yoursite.com/" />
      </Head>
      <h1>Welcome to My Next.js Site</h1>
    </div>
  );
}
```

You can add the canonical tag to other pages in the same way - just make sure to replace the href value with the correct, specifc URL for each page.

### Set the Canonical URL for article pages

For more complex sites, especially those with pages generated from Markdown or a CMS, you'll likely want to set the canonical URL dynamically. Here's a simplified example of how you might accomplish this using `next/navigation`:

```jsx
import Head from 'next/head';
import { useRouter } from 'next/navigation';

export default function BlogPost() {
  const router = useRouter();

  // ƒor https://example.com/articles/my-good-article,
  // this will contain something like "/articles/my-good-article"
  const path = router.asPath;

  /*
    Dynamically set the canonical URL - this needs to be an absolute URL
    so make sure to include the domain
    For example, if your site is https://www.yoursite.com
    and the path is /blog/my-post, the canonical URL would be
    https://www.yoursite.com/blog/my-post
  */
  const canonicalUrl = `https://www.yoursite.com${path}`;

  return (
    <div>
      <Head>
        <title>Blog Post Title</title>
        <link rel="canonical" href={canonicalUrl} />
      </Head>
      <h1>Blog Post Content</h1>
    </div>
  );
}
```

### Verify the Implementation

After adding canonical tags, it's essential to verify their implementation. You can use tools like [Google's URL Inspection Tool](https://support.google.com/webmasters/answer/9012289?hl=en) in Search Console to check if your pages are being indexed correctly with the canonical tag.

![Google Search Console showing the URL Inspection Tool](https://res.cloudinary.com/mikebifulco-com/image/upload/q_auto:eco,f_auto/v1/posts/own-your-work-with-canonical-tags/google-search-console)

*Use Google's URL Inspection Tool to verify that your pages are being indexed correctly with the canonical tag*

By following these steps, you'll ensure that search engines recognize your original content, helping you build your personal brand and protect your work from content theft.

## Bonus points: set canonical URLs in places where you crosspost

Many community blogging platforms contain tools that will let you set a canonical URL on your posts. This is a step you should absolutely take when it is available - it's a way to explicitly tell crawlers that if they're crawling your article on some other site, they should consider your original site the owner.

In other words, when you post on Dev.to, you should add metadata to your post *there* to indicate that it was *originally* posted on `yoursite.com`.

![A recent post of mine on Dev.to showing that it is a crosspost](https://res.cloudinary.com/mikebifulco-com/image/upload/q_auto:eco,f_auto/v1/posts/own-your-work-with-canonical-tags/canonical-dev-to)

*If you do it right, dev.to will point right back to your original article*

### FWIW: Adding canonical tags with Next.js App router

If your Next.js app is built using the App Router, implementation is slightly different, but also pretty straightforward. Next provides an API called [Dynamic Metadata](https://nextjs.org/docs/app/building-your-application/optimizing/metadata) on each page, which slurps up the output of a function called `generateMetadata` on your pages, and sticks the result in nicely formatted tags in the `<head />` of your document.

To add a canonical tag with this method, you'll do something like this:

```tsx
import type { Metadata, ResolvingMetadata } from 'next';

type Props = {
  params: { id: string };
  searchParams: { [key: string]: string | string[] | undefined };
};

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  // read route params
  const slug = params.slug;

  return {
    metadataBase: new Url('https://yoursite.com'), // Next will use this to make complete URLs from relative paths
    alternates: {
      canonical: `/articles/${slug}`,
    },
  };
}

export default function Page({ params, searchParams }: Props) {
  /* etc */
}
```

### Setting a canonical URL on Dev.to

To [set the canonical URL of a post on Dev.to](https://dev.to/p/editor_guide#front-matter), add `canonical_url` to the frontmatter of your post:

```md
---
title: Hello this is a post
canonical_url: https://yoursite.com/article/some-article`
---
```

### Setting a canonical URL on Medium

To [set the canonical URL of a post on Medium](https://help.medium.com/hc/en-us/articles/360033930293-Set-a-canonical-link), you'll use the three dot button `...` on your post and select "This story was originally published elsewhere" from the menu

### Setting a canonical URL on Hashnode

In the Hashnode editor, there's a helpful menu under *Draft Settings* for "Are you republishing?", where you can [specify your post's canonical URL](https://support.hashnode.com/en/articles/6556971-how-to-set-a-canonical-link).

### Setting a canonical URL on LinkedIn

LinkedIn *desperately* wants you to use their "write an article" feature to share long form content on their site. In my opinion, this is a bad idea - **LinkedIn articles do not support canonical tags** -- and IMO, this means they're trying to take credit for your work.

Instead, just share a link to your article in a regular post - it may not do as well in their feed algorithm, but at least there they'll honor your canonicals.

## Protect your work and boost your SEO with canonical tags

All told, this is a tiny amount of work to protect your IP, send search traffic your way, and build your brand. It's one of those things that many devs overlook. Building SEO traffic for your site has compounding value over time - and learning the fundamentals goes a long way.

Now get out there and add `<link rel="canonical">` to your articles, before I claim them as my own 😘

## More reading on SEO

I have [written *gobs* about SEO for developers](https://mikebifulco.com/tags/seo) - if you liked this article, you may want to out these as well:

- [How to set up self-healing URLs in Next.js for better SEO](https://mikebifulco.com/posts/self-healing-urls-nextjs-seo)
- [3 Tiny Tips for better SEO](https://mikebifulco.com/newsletter/tiny-tips-for-better-seo)
- [SEO tools I used to grow my sites to 20k+ visitors/month](https://mikebifulco.com/posts/seo-tools-for-new-web-projects)
- [The correct semantic HTML for adding subtitles to h1 tags](https://mikebifulco.com/posts/semantic-html-heading-subtitle)

## FAQ

### What is a canonical tag?

A canonical tag is a specially formatted `<link rel="canonical" href="..." />` tag that lives in the `<head>` of an HTML page. It lets you specify the original or "canonical" version of the content on that page. Search engines like Google use it, along with a few other signals, to decide which URL should be considered the official home of the content.

### When should I use a canonical tag?

Use one whenever your work appears in multiple places online, especially when you cross-post. If you publish on your own site and then cross-post to Hashnode, Medium, or Dev.to without a canonical tag, it can hurt your search rankings everywhere. The canonical tag points crawlers back to your original so the backlinks and traffic credit accrue to your site.

### How many canonical tags should a page have?

Exactly one. A page should have **only one** canonical tag. Adding more than one can have negative or unintended effects on your search rankings. In Next.js, watch out for accidentally rendering more than one `<Head />` per page.

### How do I add a canonical tag in Next.js?

With the pages router, import `Head` from `next/head` and drop a `<link rel="canonical" href="..." />` inside it, using the exact, absolute URL of the page (including a trailing slash if your URLs have one). With the app router, return an `alternates: { canonical: '/your-path' }` object from `generateMetadata`, and set `metadataBase` so Next can build complete URLs from relative paths.

### Can I set a canonical URL on platforms where I cross-post?

Yes, and you should whenever the option exists. [Dev.to](https://dev.to/p/editor_guide#front-matter) supports a `canonical_url` field in front matter, [Medium](https://help.medium.com/hc/en-us/articles/360033930293-Set-a-canonical-link) lets you mark a story as originally published elsewhere, and [Hashnode](https://support.hashnode.com/en/articles/6556971-how-to-set-a-canonical-link) has a republishing setting in Draft Settings. LinkedIn articles do not support canonical tags, so share a plain link to your original instead.

## More from mikebifulco.com

- [Add Structured Data to your Next.js site with JSON-LD for better SEO](https://mikebifulco.com/posts/structured-data-json-ld-for-next-js-sites)
- [3 Tiny tips for better SEO](https://mikebifulco.com/newsletter/tiny-tips-for-better-seo)
- [How to set up self-healing URLs in Next.js for better SEO](https://mikebifulco.com/posts/self-healing-urls-nextjs-seo)

---

Written by Mike Bifulco. Originally published at https://mikebifulco.com/posts/own-your-work-with-canonical-tags
