{{craftSnippets}}
Home Articles Plugins Starter theme Components on Github Gists About
  • Home
  • Articles
  • Basic SEO functionality for Craft CMS
Posted on Sep 28, 2019 by Piotr Pogorzelski

Basic SEO functionality for Craft CMS

SEO title Twig component on github gists.
Config for Seomate on github gists.
Learn how to set up SEO functionality in Craft CMS - with pure Twig code or using Seomate plugin.
Table of contents:
  • SEO title Twig component
  • Seomate plugin
    • seomate.php
    • How does Seomate config works?
    • Applying settings to specific template
    • Setting site name value from the field
    • Sitemaps
  • Advanced SEO plugins

Craft CMS does not provide any SEO functionality out the box - if you don't take care of it, your website won't even have <title> tag.

In this article, I will present two options for basic SEO setup - using pure Twig component and using seomate plugin.

SEO title Twig component #

This is very simple SEO component - the only thing it does is rendering <title> tag. This is useful even if you don't care about SEO at all - having site title set is very important from user experience point.

{% if craft.app.urlManager.matchedElement and craft.app.urlManager.matchedElement.uri == '__home__' %}
  {% set seoTitle = craft.app.urlManager.matchedElement.title %}
{% elseif craft.app.urlManager.matchedElement %}
  {% set seoTitle = craft.app.urlManager.matchedElement.title ~ ' - ' ~ siteName %}
{% else %}
  {% set seoTitle = siteName %}
{% endif %}
<title>{{ seoTitle }}</title>

Here's a summary of how title tag value is set:

  • If you are on entry or category page, title tag will be set to current page title. Site name will be added after it, separated from page title with dash character.
  • If you are on the homepage of your website (entry with empty URI), title tag will be set to current page title without site name appended.
  • If you are page that is not entry or category, title tag will be set to the site name.

Using similar methods we could probably create <description> meta tag and others. But it would be too much of the chore - if you want to set more SEO properties than just title, you should use a plugin.

Seomate plugin #

Seomate plugin will be perfect for setting up basic SEO functionality of the website.

Typical SEO plugins for Craft CMS provide us with "SEO settings field" for setting SEO properties per entry or category and control panel settings for setting site-wide SEO - for example default meta description value for all pages.

Seomate is different. There are are no SEO fields - in fact, there are no SEO related settings in the control panel at all. Seomate is based on PHP config file which maps existing Craft fields to SEO meta tags. The only thing that seomate adds to control panel, is SEO/social media preview (but only in Craft Pro).

seomate.php #

Here is a basic Seomate config that takes care of:

  • title tag
  • meta description
  • open graph image
  • robots meta tag

Place this code in config/seomate.php file:

<?php
return [
    // 'cacheEnabled' => false,
    'defaultProfile' => 'standard',

    'defaultMeta' => [
            'description' => ['globalSeo.globalseofields:settings.description'],
            'image' => ['globalSeo.globalseofields:settings.image'],
    ],

    'fieldProfiles' => [
        'standard' => [
            'title' => ['seoFields:settings.alternativeTitle', 'title'],
            'description' => ['seoFields:settings.description'],
            'image' => ['seoFields:settings.image'],
            'robots' => ['seoFields:settings.robots'], 
        ],
    ],
];

To output metatags, place this code in <head> section of website:

{% hook 'seomateMeta' %}

Now you need to create a global set and some fields in control panel so seomate has something to map metatags to:

  • Create a global set with defaultMeta handle. This will take care of site-wide settings.
  • Create Matrix field with handle globalseofields and add it to "default meta" global. Set min and max blocks settings to 1. It should have a single block with handle settings. Here are subfields of block:
    • description - text field. This will handle site-wide meta description.
    • image - asset field. It should be restricted to image files and allow only for one asset to be selected. This field will provide open graph image.
  • Create matrix field with handle seoFields. Once you add it to entries and categories, you will be able to set SEO settings per specific page. Set matrix field min and max blocks settings to 1. It should have single block with handle settings. Here are subfields of block:
    • alternativeTitle - text field. It will allow you to overwrite default title of page.
    • description - text field. This field will set meta description for specific entry and overwrite site-wide description.
    • image - asset field. It should be restricted to image files and to one selectable asset. This field will provide open graph image.
    • robots - dropdown field, with options values set to all and noindex, nofollow. This will give you the ability to make page ignored by search engines crawlers.

Setting all these things up probably took a few minutes. Fortunately, you don't need to do this every time you create a new Craft project. Thanks to project config functionality, you can keep both Seomate config file and project config file with all fields set up in git repository, and reuse them every time you create new Craft website.

If you are creating fields to be later reused using project config, you need to have at least two sites with different locales set up in Craft. Thanks to that, "translation method" settings will appear in field settings. Set text fields like description or alternativeTitle to be translated for each language. If you do not do that and later try to use these fields on a website with multiple languages, SEO properties will be not translatable.

How does Seomate config works? #

There are two most important parts of Seomate config file - defaultMeta and fieldProfiles.

defaultMeta takes care of site-wide settings - in this case, it maps meta description and open graph image to specific fields in global set. If you wish to, you can also set description to hardcoded string right within config file.

fieldProfiles allow you to map fields of specific entries or categories to their SEO metatags. These fields will overwrite values from defaultMeta. There is only standard profile right now - it will work for all entry sections and category groups. If you want to, you can create other profiles and have different mappings for different sections.

Note that there are two fields mapped to title in fieldProfiles. Title tag will first try to use alternativeTitle field (in seoFields matrix field) and when such field is empty or does not exist for specific entry, it will use title field instead.

You can use this overwriting functionality and populate metatags from other field values. For example, if your entry has some kind of "cover image", you can use this image for the default open graph image. Cover image will be overwritten only if you set other image in image field in seoFields matrix.

'image' => ['seoFields:settings.image', 'coverImage'],

Finally, there is 'cacheEnabled' => false setting that was commented out. When you are tinkering with Seomatic settings, uncomment it to disable cache. Otherwise you might not notice changes immediately.

Applying settings to specific template #

Every title tag value has sitename appended to it by default. This is usually expected behavior, however for the homepage we need to disable it. Hoempage title is most valuable for search engine optimalization and we want to have full control over it.

We can change this behavior using includeSitenameInTitle setting in Seomate config file - it will however be site-wide and disable appending site name everywhere. That's why we will use a bit of Twig in the homepage template.

{% set seomate = {
    config: {
        includeSitenameInTitle: false
    },
} %}

Now homepage title won't have site name appended, while titles of rest of pages will stay unchanged. You can modify many other Seomate settings for specific templates using this method.

Setting site name value from the field #

Site name value that is appended to title is the same site name that is used in the control panel for things like site (locale) switching widget. Sometimes site name is set to some internal name, like "english version" and "french version" - something that makes sense to content creators using control panel. Such site name could not be hovewer outputted to SEO metatags.

In seomate.php, you can set site name using siteName setting. This setting however cannot be mapped to Craft field - just to string or PHP variable. This won't do if our site has multiple languages and site name should be different for every one of them.

To map site name value to field in control panel, we can use bit of PHP code that will perform element query. Place this before return in seomate.php:

<?php
$globalSettings = Craft::$app->getGlobals()->getSetByHandle('globalSeo')->globalseofields->type('settings')->one();
$sitename = ($globalSettings ? $globalSettings->suffix : null) ?: Craft::$app->getSites()->getCurrentSite()->name;

This code will look for field suffix in the same global other values in defaultMeta are taken from, and assign it to PHP variable. If such a field is empty or does not exists, the default site name will still be used. Once you have site name value, set siteName config setting to $sitename variable.

'siteName' => $sitename,

Sitemaps #

Seomate provides you with sitemap functionality. Just like SEO metatags, sitemaps can be set through the config. Basic sitemap settings that need to be put in seomate.php look like this:

'sitemapEnabled' => true,
'sitemapConfig' => [
    'elements' => [
        'news' => ['changefreq' => 'weekly', 'priority' => 1],
    ],
],

This will generate a sitemap for entries in section with handle news. For more advanced sitemap settings, check documentation.

Advanced SEO plugins #

If you want to give your website more advanced SEO functionality, I suggest you to use Seomatic or Sprout Seo plugins.

Both of these plugins are paid and cost 99$ for first year of usage - but for functionality they offer, it's fair price.


TAGS:
#tutorial
If you want to get latest updates on Craft CMS tutorials and components, follow me on Twitter or subscribe to RSS feed.
Quick links for this article:
SEO title Twig component on github gists.
Config for Seomate on github gists.
Articles on blog:
  • Frontend testing for Craft CMS websites with Codeception and Cypress
  • Building reactive Craft Commerce product page with Sprig plugin
  • Dynamically generated PDF attachments for Freeform submissions
  • Using template hooks in Craft CMS
  • Alpine JS modal component for Craft CMS
  • Using template UI elements to extend Craft CMS control panel
  • Matrix within a Matrix - possible solutions for Craft CMS
  • Universal email template for Craft CMS
  • Creating attributes table from entry fields in Craft CMS
  • Namespacing forms in Craft CMS
  • Creating map-based navigation for Craft CMS
  • Placeholder image macro for Craft CMS
  • Building AJAX contact form with Craft CMS
  • Using incognito field plugin for Craft CMS
  • Email footer creator made with Craft CMS
  • Infinite scrolling and lazy loading with Craft CMS
  • Using Javascript in Twig templates with Craft CMS
  • Twig templating tips and tricks for Craft CMS
  • Basic SEO functionality for Craft CMS
  • Working with dates in Craft CMS templates
  • Working with SVG images in Craft CMS templates
  • Responsive and lazy-loaded youtube videos with Craft CMS
  • Debugging and inspecting Twig templates in Craft CMS
  • Creating article excerpts with Twig component in Craft CMS
  • Adding favicons to Craft CMS website
  • Truncating text with Twig macros in Craft CMS
  • Universal language switcher for Craft CMS
  • Read time macro for Craft CMS
  • Using attr() function to render HTML attributes in Craft CMS
  • Building dynamic, AJAX based pagination for Craft CMS
  • How to add Disqus comments to Craft CMS website
  • Ellipsis pagination component for Craft CMS
  • Converting email addresses into links using Twig macro
  • Breadcrumb created from URL for Craft CMS
  • Best developer-oriented Craft CMS plugins
  • Search autocomplete component for Craft CMS
  • RSS feed - template component for Craft CMS
  • Testing emails sent by Craft CMS using Mailtrap
  • Quick edit link - Twig component for Craft CMS
  • Filtering entries in control panel using Searchit plugin
  • Fetching routes into Twig templates in Craft CMS


Frontend testing for Craft CMS websites with Codeception and Cypress

Building reactive Craft Commerce product page with Sprig plugin

Dynamically generated PDF attachments for Freeform submissions

Using template hooks in Craft CMS

Alpine JS modal component for Craft CMS

Using template UI elements to extend Craft CMS control panel

Matrix within a Matrix - possible solutions for Craft CMS

Universal email template for Craft CMS

Copyright ©2023 Piotr Pogorzelski