Skip to content
On this page

SEO Technologies

Pagination and SEO

If you are using paginated entries, you’ll want to add some additional markup to your templates to make Google et al aware of this. Fortunately, SEOmatic makes that easy, you simply do:

{% do seomatic.helper.paginate(PAGEINFO) %}

The PAGEINFO here is the variable from the {% paginate %} tag as described here, this will properly set the canonicalUrl, as well as adding the <link rel='prev'> and <link rel='next'> tags for you.

A complete example (just a modified version of the Craft 3 Documentation on {% Paginate %}) might look like this:

{% paginate craft.entries.section('blog').limit(10) as pageInfo, pageEntries %}
{% do seomatic.helper.paginate(pageInfo) %}

{% for entry in pageEntries %}
        <h1>{{ entry.title }}</h1>
        {{ entry.body }}
{% endfor %}

{% if pageInfo.prevUrl %}<a href="{{ pageInfo.prevUrl }}">Previous Page</a>{% endif %}
{% if pageInfo.nextUrl %}<a href="{{ pageInfo.nextUrl }}">Next Page</a>{% endif %}

More info: SEO Guide to Google Webmaster Recommendations for Pagination

Multi-Site Language/Locale Support

SEOmatic comes with multi-site support baked in. Each site has its own localized settings that can be different on a per-site basis.

Craft CMS defines Sites as any combination of site settings and locale (language). But there needs to be some way to organize these sites to define a relationship between them. That’s what Site Groups are for.

SEOmatic treats each Site Group as a separate entity, and any sites contained in that site group are treated as localizations of the same site.

This is necessary because there needs to be some way to let SEOmatic know what the relationship is between the various sites.

So for example, you might have:

├── Primary Site Group
│   ├── English Site
│   ├── Chinese Site
|   └── German Site
├── Sister Site Group
│   ├── English Site
|   └── German Site

While you technically don’t have to organize your Site Groups in this manner, SEOmatic currently requires it so that it can understand the relationship between your sites.

This is necessary because for a variety of SEO-related things, we need to tell search engines what is really just another localization/translation of the same thing.

If you don’t want to organize your sites in this manner, you’ll need to turn off the Site Groups define logically separate sites setting on the Plugin Settings page.

Sites that are grouped together under the same Site Group will have <link rel="alternate" hreflang="XX"> & <meta content="xx_XX" property="og:locale:alternate"> URLs added automatically in the HTML.

To disable SEOmatic’s automatic rendering of these tags, you can do:

{% do seomatic.tag.get('alternate').include(false) %}
{% do seomatic.tag.get('og:locale:alternate').include(false) %}

Sites that are grouped together under the same Site Group will also be included in the appropriate sitemap indexes, and have <xhtml:link rel="alternate" hreflang="xx-xx"> tags added to the respective sitemaps.

To disable the generation of the <xhtml:link rel="alternate" hreflang="xx-xx"> on a per-Entry basis, you can do this by adding an SEO Settings to the Section/Category Group/Product in question, and turn off Sitemap Enabled on a per-entry basis.

Plugin Support

SEOmatic automatically works with the following plugins:

This means that SEOmatic will treat the Elements that these plugins provide as first class citizens, just like Craft Entries & Categories.

SEOmatic will generate metadata, sitemaps, and have a Craft CP UI for them. If you have a custom Element provided by a plugin or module, you can integrate it using the SeoElementInterface.

Emoji Support

SEOmatic supports using Emojis in any of the fields in SEOmatic, so you could use one in the SEO Description, for instance:


It’s up to Google whether or not to display the emojis that you add to your SEO meta, but used effectively, they can help make your entries in the SERP stand out from others. Learn more: Why Use Emojis in Your SEO / PPC Strategy?


On the Mac, you can invoke an Emoji keyboard inside of any text field by hitting Command Control Space. This works in any Mac application, not just web browsers or SEOmatic.

Google AMP Support

SEOmatic works great with Google AMP! In fact, it will provide the JSON-LD structured data that is required by the AMP spec.

You do however need to Make your page discoverable:

Add the following to the non-AMP template to tell Google where the AMP version of the page is; yourAmpPageLink the URL to your AMP page:

{% set linkTag ={
  "rel": "amphtml",
  "href": yourAmpPageLink

And this to the AMP template to tell Google where the canonical HTML page is:

{% do seomatic.meta.canonicalUrl(entry.url) %}

Since AMP doesn’t allow for third-party JavaScript, you might want to add this to your AMP templates:

{% do seomatic.script.container().include(false) %}

This will cause SEOmatic to not render any custom scripts you might have enabled (such as Google Analytics, gtag, etc.)

Then you can include Google AMP Analytics as per Adding Analytics to your AMP pages (this assumes you’re using gtag):

{% set script = seomatic.script.get('gtag') %}
{% set analyticsId = script.vars.googleAnalyticsId.value ??? '' %}
<amp-analytics type="googleanalytics">
    <script type="application/json">
            "vars": {
                "account": "{{ analyticsId }}"
            "triggers": {
                "trackPageview": {
                    "on": "visible",
                    "request": "pageview"

The above uses the ??? empty coalesce operator that comes with SEOmatic; check out SEOmatic’s ??? Empty Coalesce operator for details.

Single Page App (SPA) Support

SEOmatic fully supports working with SPAs, allowing you to receive the metadata needed for a given route either as an array, or as DOM elements ready to be inserted.

See the Headless SPA API section for details.

Brought to you by nystudio107