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 to1
. It should have a single block with handlesettings
. 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 to1
. It should have single block with handlesettings
. 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 toall
andnoindex, 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.