Define Canonical URL in a Hugo Theme
Reading time: 2 minutes
Hugo is a Static site
generator, but links to
your site may contain optional parameters like ref=...
which may produce
duplicate content for search engines. You can use canonical URL to define, which
URL should be used by Google and co.
Google has a very detailed description how to consolidate duplicate URLs.
If you know Hugo and want just a copy a paste solution, just add this in head of your template:
<head>
...
<link rel="canonical" href="{{ .Permalink }}">
...
</head>
This will result in an URL like:
<head>
<link rel="canonical" href="https://qameta.com/posts/your-blog-post/">
</head>
Using relative URLs may be wrong
According to Google documentation for content. It is important to use absolute URL in your canonical URL definition. Some online resources say, that you should use relative permalink:
<head>
<link rel="canonical" href="{{ .RelPermalink }}">
</head>
This would result to this output:
<head>
<link rel="canonical" href="/posts/your-blog-post/">
</head>
The missing Domain is considered to be wrong.
Use absolute URLs
Using absolute URLs is an important part for canonical URLs, as you may cross post content on your other sites or external media site (like Medium), which may have the same link structure, but a different domain.
Lookup in your project folder my-website/themes/ for your Hugo Theme. There should be a folder layouts/ where the base structure of your HTML site is defined. There find the part, where <head> is defined. For my themes it is in /layouts/partials/head.html.
Just a hint, you can grep for it in your themes folder:
$ grep -R "<head>" .
./themes/your-theme/layouts/partials/head.html:<head>
Open the file where your <head> part of the website is defined and add it:
<head>
...
<link rel="canonical" href="{{ .Permalink }}">
...
</head>
This will result in an URL like:
<head>
<link rel="canonical" href="https://qameta.com/posts/your-blog-post/">
</head>
Summary
This is a simple solution to add canonical URLs to every page through Hugo Theme of your choice. A lot of themes have already this or a similar line included. If your theme does not have it, you should add it, to reduce the chance of content marked as duplicate due to URL parameters.
This solution does not handle internationalization. You may also want to define, where the content is cross posted, what is according to moz.com: Using the Cross Domain Rel=Canonical to Maximize the SEO Value of Cross-Posted Content an import part of content distribution.