Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

10. Dynamic Twig SEO Meta

Andrew Welch edited this page Feb 21, 2018 · 5 revisions

Dynamic Twig SEO Meta

All this SEO is great, but what if you want to generate dynamic SEO in an Twig template, with custom or specific requirements that the SEOmatic FieldType can't handle? SEOmatic makes it easy.

SEOmatic populates your templates with the following global variables for SEO Meta:

seomaticMeta.seoTitle
seomaticMeta.seoDescription
seomaticMeta.seoKeywords
seomaticMeta.seoImage
seomaticMeta.canonicalUrl

By default, seomaticMeta.canonicalUrl is set to craft.request.url.

All of the variables are set by a combination of your SEO Site Meta settings, and the SEO Template Meta settings linked to the currently rendered template (if any). These are the primary SEOmatic variables that you will be manipulating in your templates.

By the time the various SEOmatic variables are populated into your template, SEOmatic has applied all of the cascading meta from your Site Meta, Template Meta, and Entry Meta. The variables are all set, and will not be manipulated further by SEOmatic, only output.

So you can change the variables as you see fit; but it also means that if you change your seoImage, for example, it will not change the og:image. This is so that you can manipulate them independently.

Important: Due to the way Twig scoping works, if you {% include %} a template, it's given a copy of the current Twig context (variables, etc.), which means that any changes made there are not propagated back to the parent template.

So for instance if you {% include %} a template that changes some SEOmatic variables, they will not be changed in the parent context's scope, so they will not be rendered by SEOmatic.

You'll need to modify the SEOmatic variables in a template that {% extends %} the main layout.twig template or via Twig embeds.

These work like any other Twig variables; you can output them by doing:

{{ seomaticMeta.seoTitle }}

If you have a Twitter Handle, you'll also get variables that are used to generate your Twitter Card tags:

seomaticMeta.twitter.card
seomaticMeta.twitter.site
seomaticMeta.twitter.creator
seomaticMeta.twitter.title
seomaticMeta.twitter.description
seomaticMeta.twitter.image

You'll also get variables that are used to generate your Facebook Open Graph tags:

seomaticMeta.og.type
seomaticMeta.og.locale
seomaticMeta.og.url
seomaticMeta.og.title
seomaticMeta.og.description
seomaticMeta.og.image
seomaticMeta.og.site_name
seomaticMeta.og.see_also

When SEOmatic goes to render the twitter, og and article namespace tags, it iterates through the respective arrays, so you can add, remove, or change any of the key-value pairs in the array, and they will be rendered. Just ensure that the key is a valid schema type for the respective meta tags.

You can even do fun things like:

{% set seomaticMeta = seomaticMeta | merge({
    og: { 
        type: seomaticMeta.og.type,
        locale: seomaticMeta.og.locale,
        url: entry.url,
        title: "Some Title",
        description: entry.summary,
        image: ['one.jpg', 'two.jpg', 'three.jpg'],
        site_name: seomaticMeta.og.site_name,
        see_also: seomaticMeta.og.see_also
    }
}) %}

...and SEOmatic will output 3 og:image tags, one for each image in the array. Because of the way that Twig handles arrays, you must include every field in the array when doing a set or merge, otherwise the fields you exclude will not exist.

You can also change them all at once like this using the Twig set syntax:

{% set seomaticMeta = { 
    seoTitle: "Some Title",
    seoDescription: entry.summary,
    seoKeywords: "Some,Key,Words",
    seoImage: seomaticMeta.seoImage,
    canonicalUrl: entry.url,
    twitter: { 
        card: seomaticMeta.twitter.card,
        site: seomaticMeta.twitter.site,
        creator: seomaticMeta.twitter.creator,
        title: "Some Title",
        description: entry.summary,
        image: seomaticMeta.twitter.image
    },
    og: { 
        type: seomaticMeta.og.type,
        locale: seomaticMeta.og.locale,
        url: entry.url,
        title: "Some Title",
        description: entry.summary,
        image: seomaticMeta.og.image,
        site_name: seomaticMeta.og.site_name,
        see_also: seomaticMeta.og.see_also
    }
} %}

Anywhere we are setting a field to seomaticMeta.*, we're setting it to what it already is, essentially saying to leave it unchanged. We do this because Twig requires that you pass in the entire array to the set operator.

If you're using the article OpenGraph type, you'll see an additional article namespace array in your seomaticMeta:

{% set seomaticMeta = { 
    seoTitle: "Some Title",
    seoDescription: entry.summary,
    seoKeywords: "Some,Key,Words",
    seoImage: seomaticMeta.seoImage,
    canonicalUrl: entry.url,
    twitter: { 
        card: seomaticMeta.twitter.card,
        site: seomaticMeta.twitter.site,
        creator: seomaticMeta.twitter.creator,
        title: "Some Title",
        description: entry.summary,
        image: seomaticMeta.twitter.image
    },
    og: { 
        type: seomaticMeta.og.type,
        locale: seomaticMeta.og.locale,
        url: entry.url,
        title: "Some Title",
        description: entry.summary,
        image: seomaticMeta.og.image,
        site_name: seomaticMeta.og.site_name,
        see_also: seomaticMeta.og.see_also
    },
    article: { 
        author: "Some Author",
        publisher: "Some publisher",
        tag: "some,tags"
    }
} %}

Or if you want to set just one variable in the array, you can use the Twig function merge:

{% set seomaticMeta = seomaticMeta | merge({'seoDescription': entry.summary }) %}

Here's an example of how to change just the image in Twitter:

{% set twitter = seomaticMeta.twitter %}
{% set twitter = twitter | merge({'image': someImage}) %}
{% set seomaticMeta = seomaticMeta | merge({'twitter': twitter}) %}

...and here's an example of how to change just the image in OpenGraph:

{% set og = seomaticMeta.og %}
{% set og = og | merge({'image': someImage}) %}
{% set seomaticMeta = seomaticMeta | merge({'og': og}) %}

Here's an example of setting it to not append the SEO Site Name to the title tag:

{% set seomaticSiteMeta = seomaticSiteMeta | merge({'siteSeoTitlePlacement': 'none'}) %}

You can change these seomaticMeta variables in your templates that extends your main layout.twig template, and due to the Twig rendering order, when {% hook 'seomaticRender' %} is called, they'll be populated in your rendered SEO Meta tags.

Some of the seomaticMeta variables have character limitations on them, because search engines want to see only the most relevant, succinct information, and will truncate them during processing:

  • seomaticMeta.seoTitle - 70 characters
  • seomaticMeta.seoDescription - 160 characters
  • seomaticMeta.seoKeywords - 200 characters

SEOmatic will automatically truncate these variables for you when you set them, so you don't have to worry about the length. It intelligently truncates them on whole-word boundaries, so nothing will get cut off.

SEOmatic also automatically strips HTML/PHP tags from the variables, and translates HTML entities to ensure that they are properly encoded.