I have been helping a friend out with his blog which uses the Craft CMS together with the SEOmatic plugin. While I was writing an article for his blog, I noticed in his blog's HTML that the SEOmatic plugin creates a canonical link that refers to his blog instead of that of the guest. This ultimately leads to two competing canonical links which then means that both blogs are harmed in search engine rankings, especially the guest author as Google interprets the guest author's blog as plagiarizing.

To fix this issue, we needed to allow my friend to specify a separate canonical URL (the post URL from the guest blog). In today's post, I will show you how to specify an alternative canonical URL in the Craft CMS with SEOmatic.

Even though I do not use SEOmatic (or even Craft CMS for that matter), I am pretty good at developing a mental model of how things are put together which then allows me to distill problems down to their essence. This mental model then allows me to learn just enough of the framework that I can pinpoint exactly where I can write some code to fix the problem. I like to call this kind of development "sharpshooting development". This case is one such example.

Creating a New Field in Craft

In order to specify an alternative canonical URL, we first need to create a new field for it in Craft.

1. Begin by going to Settings > Fields:

2. Go to the appropriate field group and create the new field:

Creating a new field in Craft CMS
Creating a new field in Craft CMS

You can figure out which is the appropriate field group by looking at what sorts of fields are in each and just adding the field where it makes sense.

3. Give the field a name and a handle. In our case, since we're creating an alternative canonical URL for the guest blog, we'll just call it altCanonicalUrl:

Editing the properties of the new field in Craft
Editing the properties of the new field in Craft

I chose a plain text field type here, though you could probably do a URL type instead.

Make the Field Available In Your Entries

Now we need to add this field to a field type for our section. This allows us to actually see the field and edit it when we add a blog post. (In this example, we're going to use the "News" section found in Craft's demo as a proxy for a blog section).

4. Go to Settings > Sections:

5. Edit the entry type for the appropriate section of your site:

As I said before, in this tutorial, we're going to use the "News" section found in Craft's demo as a proxy for a blog section.

6. Create a new tab:

Creating a new tab in Craft CMS.
Creating a new tab in Craft CMS.

(Note that you can change the name of the tab by clicking the gear icon next to it when it appears).

7. Drag your new altCanonicalUrl field to your new tab:

Drag our new field to the new tab in Craft CMS.
Drag our new field to the new tab in Craft CMS.
New field entered under tab in Craft CMS.
New field entered under tab in Craft CMS.

You can see the result of what we've just done under Entries:

Update Our Template To Make SEOmatic Respect Our New Field:

We now have a field to store our alternative canonical URL for the guest blog. Next, we just need to handle SEOmatic so that, when the above field is populated, SEOmatic uses that URL instead of just the current blog's post URL. This can be accomplished by tracking down our template which contains the following SEOmatic render hook:

{% hook 'seomaticRender' %}

And just above it, inserting the following so that it appears as so:

{% if entry.altCanonicalUrl|length > 0 %}
    {% set seomaticMeta = seomaticMeta | merge({'canonicalUrl': entry.altCanonicalUrl}) %}
{% endif %}

{% hook 'seomaticRender' %}

Source: David Ball on Stack Exchange

I wish I could take credit for this, since it's so elegant, but a worker is due his wages. Let's look at what this code is doing:

The first piece {% if entry.altCanonicalUrl|length > 0 %} is simply checking to see if the altCanonicalUrl field is populated (length > 0). If it is, it's simply merging it with the SEOmatic canonicalUrl hash (what we would call a dictionary in Python or, in Javascript, an object; it's just a key-value pair). Nice and clean, eh?

Now, when the field is populated in Craft, SEOmatic will attribute the canonical URL to the appropriate source.


Thanks for reading. Have a great week everyone!