Canonical Snippet Tutorial

If you use this extra and like it, please consider donating. The suggested donation for this extra is $5.00, but any amount you want to give is fine (really). For a one-time donation of $50.00 you can use all of my non-premium extras with a clear conscience.

The Canonical snippet places a proper canonical tag in the head section of pages. Version 3.0.0-pl has been updated for MODX 3 and adds an option to put a canonical tag on all pages. All the information below applies to both versions of MODX.

Important update note: As of version 3.0.0-pl, Canonical will put a canonical tag on all pages. On all but SymLink pages, the tag will point to the page itself.

If you don't want this, change the canonical_always System Setting, but see the info below before doing so.

Installing Canonical

Go to Extras | Installer on the main menu in the MODX Manager. That will take you to the Package Management panel. Click on the "Download Extras" button. That will take you to the MODX Extras Repository. Put Canonical in the search box and press Enter. Click on the "Download" button, and once the package is downloaded, click on the "Back to Package Manager" button. That should bring you back to your Package Management grid. Click on the "Install" button next to Canonical in the grid and complete the steps. The Canonical package should now be installed.


Place the following tag in the <head> section of all templates:

  /* Or to have the tag only on SymLink-related pages:
[[!Canonical? &canonical_always=`0`]]

The exclamation point above is critical, leaving it out will cause search engines to hate your site.

Why put a Canonical Tag on All Pages?

SEO experts have been recommending a canonical tag on all pages, and reportedly Google has confirmed that this is a best practice.

With version 3.0.0-pl, this actually improves performance as well, since the snippet takes less time to decide whether the page gets a canonical tag. When the snippet is set to put tags on only some pages, there's no way to be sure whether a page should get a canonical tag or not without a DB query, since with the default configuration of MODX, the class_key of the document has been changed to modDocument by the time the snippet runs.

The Good News

The good news is that if you want a canonical tag on every page, you just need to update the snippet, and it should do that by default, since the extra's new canonical_always System Setting is set to Yes by default.

The Bad News

SymLinks are still complicated. There are three System Settings that control how SymLinks are handled in the Canonical snippet, and by MODX: canonical_always, symlink_merge_fields and forward_merge_excludes. The first one is created by Canonical, the other two are MODX core settings.

Tip: You can usually see all three settings by going to System (gear icon) -> System Settings, and putting "merge" in the search box. I added "merge" in parentheses after the canonical_always setting name, just so you could do that. MODX can be finicky about this because of the way I had to do it. If the canonical_always setting isn't shown, put canonical in the search box.

How Canonical Works

In the following sections, the "target" resource is the resource a SymLink page points to. The canonical tag should hold the URL of the target resource (always). The SymLink resource itself holds that target resource's ID in its content field. (When creating or editing a SymLink page, the content field of the resource gets the label: "SymLink.")

When the canonical_always setting is set to Yes, Canonical puts a canonical tag on every page that has the Canonical snippet tag in its template, regardless of the other two settings.

The symlink_merge_fields System Setting tells MODX whether to merge the SymLinks fields over those of the target document. If it's set to Yes, MODX will replace the target page's fields with any non-empty fields (including TVs) in the SymLink resource (except the ones specified below). If symlink_merge_fields is set to Yes, for example, the displayed page will use the pagetitle, longtitle, template, and other fields of the SymLink resource if they are not blank and not covered by the next section.

If the symlink_merge_fields System Setting is set to No, all the target resource's fields are used as is, and all fields of the SymLink resource are ignored, except the ID in the content field that points to the target resource.

The forward_merge_excludes System Setting contains a list of fields that should not be overwritten in the target resource when it's accessed through a SymLink. If symlink_merge_fields is set to No, these are ignored. If it's set to Yes, those fields are not overwritten by the SymLink's fields.

The default content of the forward_merge_excludes System Setting is type,published,class_key. With that setting, the value of those three fields will always come from the target resource.

Internally, MODX adds the following fields to the ones listed above (in the forward_merge_excludes setting) when it processes SymLinks. The fields listed below will always come from the target resource.

  • 'content'
  • 'pub_date'
  • 'unpub_date'
  • 'richtext'
  • '_content'
  • '_processed'

Behavior of the Canonical Snippet

The information above affects how the Canonical snippet behaves. The actions below are not my choices for the snippet, they are unavoidable effects of how MODX handles SymLinks. This is how it works:

  • canonical_always set to Yes
    • All pages get a canonical tag regardless of the other System Settings. For SymLink resources, it contains the target resource's URL, for all other pages, it contains the URL of the page itself.
  • canonical_always set to No
    • symlink_merge_fields set to Yes
      • SymLinks get a canonical tag. Other pages do not.
    • symlink_merge_fields set to No
      • SymLinks and target pages both get a canonical tag. Other pages do not.


Best choice: let the snippet put a canonical tag on every page. It's faster, better for SEO, and lets you use the System Settings however you like.

If you don't want canonical tags on every page, use the list of actions above to see what works best for your use case.

Note that if you want canonical tags only> on SymLink pages, the only way to do it is to set the symlink_merge_fields System Setting to Yes. (This is the default setting in new MODX installs.)

This means that the SymLink resource's non-empty fields and TV values will overwrite the target resource's fields, unless you add them to the forward_merge_excludes System Setting, or make sure they're blank in the SymLink resource.

When putting canonical tags on every page, it will be fastest if the symlink_merge_fields System Setting is off. In that case, no queries to the DB will be necessary. No matter what the settings or properties are, though, there will never be more than one call to the DB, so the speed advantage here is very small. If you don't need to use any fields of the SymLink resource in the final page, turn off the symlink_merge_fields setting to get faster page loads.

When putting canonical tags only on SymLink-related pages, having the symlink_merge_fields System Setting off is also faster since it can use getCount() rather than retrieving an object, but the difference is probably negligible, since the getCount() call has criteria.

Note that using a different template for SymLink pages and putting the Canonical snippet tag only on that template doesn't work. If you do that, SymLink pages will never get a canonical tag.

What about WebLinks?

WebLinks actually forward the user to the target page, potentially with a 301 (permanently moved) response code, so you won't be penalized for duplicate content.

WebLinks might seem like a simpler alternative to Symlinks, but there are two drawbacks with WebLinks. First, you won't get to use any fields of the WebLink on the target page like you can with SymLinks.

Second, a SymLink pulls in the content of the target page and displays it, all in the same request cycle. A WebLink, on the other hand, instantiates MODX, initializes MODX, finds the page to display, then forwards the user to the target page, which begins another request, so MODX is instantiated and initialized all over again, slowing down your page loads.

My book, MODX: The Official Guide - Digital Edition is now available here. The paper version of the book may still be available from Amazon.

If you have the book and would like to download the code, you can find it here.

If you have the book and would like to see the updates and corrections page, you can find it here.

MODX: The Official Guide is 772 pages long and goes far beyond this web site in explaining beginning and advanced MODX techniques. It includes detailed information on:

  • Installing MODX
  • How MODX Works
  • Working with MODX resources and Elements
  • Using Git with MODX
  • Using common MODX add-on components like SPForm, Login, getResources, and FormIt
  • MODX security Permissions
  • Customizing the MODX Manager
  • Using Form Customization
  • Creating Transport Packages
  • MODX and xPDO object methods
  • MODX System Events
  • Using PHP with MODX

Go here for more information about the book.

Thank you for visiting

  —  Bob Ray