SEOmatic facilitates modern SEO best practices & implementation for Craft CMS 3. It is a turnkey SEO system that is comprehensive, powerful, and flexible.
Related: SEOmatic for Craft 2.x. SEOmatic for Craft CMS 3 is a complete re-write & re-architecture from scratch.
Note: The license fee for this plugin is $99.00 via the Craft Plugin Store.
One SEO-related topic that SEOmatic does not cover is 404 redirects; for that we recommend our Retour plugin.
SEOmatic is the SEO tool that the SEO experts at Moz.com and the creators of Craft CMS, Pixel & Tonic, rely on to handle their SEO!
This plugin requires Craft CMS 3.0.20 or later.
To install SEOmatic, follow these steps:
- Install with Composer via
composer require nystudio107/craft-seomatic
- Install plugin in the Craft Control Panel under Settings > Plugins
You can also install SEOmatic via the Plugin Store in the Craft Control Panel.
SEOmatic works on Craft 3.x.
Please report any issues you find to the SEOmatic Issues page.
If you are upgrading a site from Craft CMS 2.x to Craft CMS 3.x that used the older SEOmatic plugin, here's what you need to know.
SEOmatic will migrate your old Craft 2.x Field settings & data in the following ways:
-
The Content SEO settings for each Section where you had an old SEOmatic Meta FieldType will be migrated for you.
-
If you add a new SEO Settings Field to a section that had an old SEOmatic Meta field in it, it will migrate any custom data you had entered on a per-Entry basis
Important: Keep your old Craft 2.x Seomatic_Meta fields intact; don't delete them or change the Field type to the new SEO Settings field type. Instead, create a new SEO Settings field in the same Section, Category Group, or Commerce Product Type. It will automatically look for and migrate data from the old Seomatic_Meta Field.
SEOmatic for Craft CMS 3 is a complete re-write and re-architecture from scratch of the plugin. This allowed us to take what we learned from SEOmatic 1.x, and rebuild it with a much more robust and extendable architecture.
If feasible, we think the best way to update sites using SEOmatic is to start fresh, and explore how the conceptual changes in the plugin affect how you use it. In most cases, you don't even need to use an SEOmatic Field, and the setup is cleaner and easier without it! We hope you love it!
N.B.: The Twig templating syntax has changed (but you may not need to use Twig at all with the new version), so give the docs a once-over.
SEOmatic facilitates modern SEO best practices & implementation for Craft CMS 3. It is a turnkey SEO system that is comprehensive, powerful, and flexible.
SEOmatic allows you to quickly get a website up and running with a robust, comprehensive SEO strategy. It is also implemented in a Craft-y way, in that it is also flexible and customizable.
It implements JSON-LD microdata, Twitter Cards tags, Facebook OpenGraph tags, Sitemaps of your content, Robots.txt bot directives, Humans.txt authorship accreditation, and as well as HTML meta tags.
SEOmatic populates your templates with SEO Meta in the same way that Craft populates your templates with entry
variables, with a similar level of freedom and flexibility in terms of how you utilize them.
SEOmatic works automatically with Craft Commerce 2 as well, providing metadata, JSON-LD structured data, and sitemaps for your Products.
SEOmatic also caches each unique SEO Meta request so that your website performance is minimally impacted by the rich SEO Meta tags provided.
As soon as you install SEOmatic, it automatically will render meta data on your web pages, and create sitemaps for all of your Sections, Category Groups, and Commerce Product Types that have public URLs. You don't need to add any template code for this to happen.
All of SEOmatic's settings are multi-site aware, allowing you to have different settings for each site/language combination.
For SEOmatic to be truly useful, you need to configure it so that it knows where to pull SEO content from.
N.B. Please ensure that you set up your Multi-Environment Config Settings if you will be using SEOmatic across multiple environments.
The Dashboard gives you an overview of how fully set up your SEO setting in SEOmatic are, for Global SEO, Content SEO, and Site Settings.
Click on any of the graphs to jump to the section in question to fill things out in more detail.
Global SEO is where you set all of the default site-wide settings.
Best practices for modern SEO are for the meta information to reflect your content, so you should set up the fields that SEOmatic pulls the SEO Title, SEO Description, and SEO Image from.
By default, the Twitter and Facebook settings will mirror what you set in the General section, but you can customize them to your heart's content.
By default, the Twitter and Facebook settings will mirror what you set in the General section, but you can customize them to your heart's content.
A robots.txt
file is a file at the root of your site that indicates those parts of your site you don’t want accessed by search engine crawlers. The file uses the Robots Exclusion Standard, which is a protocol with a small set of commands that can be used to indicate access to your site by section and by specific kinds of web crawlers (such as mobile crawlers vs desktop crawlers).
You shouldn't need to edit the default robots.txt
Template, but you can if you like.
SEOmatic automatically handles requests for /robots.txt
. For this to work, make sure that you do not have an actual robots.txt
file in your web/
folder (because that will take precedence).
If you are running Nginx, make sure that you don't have a line like:
location = /robots.txt { access_log off; log_not_found off; }
...in your config file. A directive like this will prevent SEOmatic from being able to service the request for /robots.txt
. If you do have a line like this in your config file, just comment it out, and restart Nginx with sudo nginx -s reload
.
The View robots.txt button lets you view your rendered robots.txt
.
Humans.txt is an initiative for knowing the people behind a website. It's a text file that contains information about the different people who have contributed to building the website. By adding a text file, you can prove your authorship (not your property) in an external, fast, easy and accessible way.
Feel free to edit the default humans.txt
Template to your heart's content.
The View humans.txt button lets you view your rendered humans.txt
.
The ads.txt project is simple: Increase transparency in the programmatic advertising ecosystem. ads.txt stands for Authorized Digital Sellers and is a simple, flexible and secure method that publishers and distributors can use to publicly declare the companies they authorize to sell their digital inventory.
Feel free to edit the default ads.txt
Template to your heart's content.
The View ads.txt button lets you view your rendered ads.txt
.
The fields in the Control Panel Global SEO settings are parsed as Twig object templates, so in addition to plain old text, you can also put single and double bracket Twig expressions.
This is entirely optional; in typical usage the controls you have in the Control Panel for pulling from other fields will be all you need. But the ability is there if you need it.
For example, the following will output the contents of the companyInfo field from the siteInfo Global:
{{ siteInfo.companyInfo }}
You can even do complex expressions, such as the following which outputs the first field that isn't empty, or a default text:
{{ siteInfo.companyInfo ?? siteInfo.companySummary ?? "Some default text" }}
You can also access SEOmatic global variables (discussed below):
{seomatic.meta.seoTitle}
Normal Twig double bracket syntax is supported too, but you'll need to preface it with object.
for any seomatic
variables:
{{ object.seomatic.meta.seoTitle }}
The single bracket syntax is just a shortcut that automatically prefixes any variables with object.
, and it used for micro-template parsing.
Content SEO is where you can configure each Section, Category Group and Commerce Product Type that has public URLs. You'll see a list of all of your Sections, Category Groups, and Commerce Product Types that have public URLs, with status indicators letting you know what has been configured for each.
Click on a Section, Category Group, or Commerce Product Type name to edit its settings.
Best practices for modern SEO are for the meta information to reflect your content, so you should set up the fields that SEOmatic pulls the SEO Title, SEO Description, and SEO Image from.
By default, the Twitter and Facebook settings will mirror what you set in the General section, but you can customize them to your heart's content.
By default, the Twitter and Facebook settings will mirror what you set in the General section, but you can customize them to your heart's content.
SEOmatic automatically creates a sitemap index for each of your Site Groups. This sitemap index points to individual sitemaps for each of your Sections, Category Groups, and Commerce Product Types.
Instead of one massive sitemap that must be updated any time anything changes, only the sitemap for the Section, Category Group, or Commerce Product Type will be updated when something changes in it.
SEOmatic can automatically include files such as .pdf
, .xls
, .doc
and other indexable file types in Asset fields or Asset fields in matrix or Neo blocks.
In addition, SEOmatic can automatically create Image sitemaps and Video sitemaps from images & videos in Asset fields or Asset fields in matrix or Neo blocks
Sitemap Indexes are automatically submitted to search engines whenever a new Section, Category Group, or Commerce Product Type is added.
Section Sitemaps are automatically submitted to search engines whenever a new Element in that Section, Category Group, or Commerce Product Type is added.
Because XML sitemaps can be quite time-intensive to generate as the number of entries scales up, SEOmatic creates your sitemaps via a Queue job, and caches the result. The cache is automatically broken whenever something in that sitemap is changed, and a new Queue job is created to regenerate it.
If runQueueAutomatically
is set to false
in General Config Settings the Queue job to create the sitemap will not be run during the http request for the sitemap. You'll need to run it manually via whatever means you use to run the Queue.
Normally SEOmatic will regenerate the sitemap for a Section, Category Group, or Product any time you save an element. However, if you are importing a large number of elements, or prefer to regenerate the sitemap manually you can set disable the Regenerate Sitemaps Automatically option in SEOmatic's Plugin Settings.
You can then regenerate the sitemap via CLI. This will regenerate all sitemaps:
./craft seomatic/sitemap/generate
You can also limit it to a specific Section, Category Group, or Product handle:
./craft seomatic/sitemap/generate --handle=blog
...or you can regenerate all sitemaps for a specific siteId
:
./craft seomatic/sitemap/generate --siteId=1
...or both:
./craft seomatic/sitemap/generate --handle=blog --siteId=1
N.B.: If you do disable Regenerate Sitemaps Automatically sitemaps will not be updated unless you do so manually via the CLI, or clear SEOmatic's sitemap caches via Utilities->Clear Caches.
If you have custom sitemaps that are not in the CMS, you can manually add them to their own Sitemap Index via Site Settings → Sitemap.
You can also add to it via a plugin:
use nystudio107\seomatic\events\RegisterSitemapsEvent;
use nystudio107\seomatic\models\SitemapIndexTemplate;
use yii\base\Event;
Event::on(SitemapIndexTemplate::class, SitemapIndexTemplate::EVENT_REGISTER_SITEMAPS, function(RegisterSitemapsEvent $e) {
$e->sitemaps[] = [
'loc' => $url,
'lastmod' => $lastMod,
];
});
If you have custom URLs that are not in the CMS, you can manually add them to their own Sitemap Index via Site Settings → Sitemap.
You can also add to it via a plugin:
use nystudio107\seomatic\events\RegisterSitemapUrlsEvent;
use nystudio107\seomatic\models\SitemapCustomTemplate;
use yii\base\Event;
Event::on(SitemapCustomTemplate::class, SitemapCustomTemplate::EVENT_REGISTER_SITEMAP_URLS, function(RegisterSitemapUrlsEvent $e) {
$e->sitemapUrls[] = [
'loc' => $url,
'changefreq' => $changeFreq,
'priority' => $priority,
'lastmod' => $lastMod,
];
});
The fields in the Control Panel Content SEO settings are parsed as Twig object templates, so in addition to plain old text, you can also put single and double bracket Twig expressions.
This is entirely optional; in typical usage the controls you have in the Control Panel for pulling from other fields will be all you need. But the ability is there if you need it.
For example, the following will output the contents of the description field from the current Entry:
{entry.description}
Normal Twig double bracket syntax is supported too, but you'll need to preface it with object.
:
{{ object.entry.description }}
The single bracket syntax is just a shortcut that automatically prefixes any variables with object.
, and it used for micro-template parsing.
The same applies to any SEOmatic global variables (discussed below):
{seomatic.meta.seoTitle}
Is the same as:
{{ object.seomatic.meta.seoTitle }}
You can even do complex expressions, such as the following which outputs the first field that isn't empty, or a default text:
{entry.description ?? entry.summary ?? "Some default text"}
Is the same as:
{{ object.entry.description ?? object.entry.summary ?? "Some default text" }}
These Site Identity settings are used to globally define the identity and ownership of the website.
They are used in combination with the SEO Template Meta settings to generate JSON-LD microdata.
The Site Owner type determines the JSON-LD schema that will be used to identity the website to search engines.
Leave any fields blank that aren't applicable or which you do not want as part of the SEO schema.
These Site Creator settings are used to globally define the creator (such as the agency or freelancer) of the website.
They are used in combination with the SEO Template Meta settings to generate JSON-LD microdata as well as the humans.txt
file.
The Site Creator type determines the JSON-LD schema that will be used to identity the website to search engines.
Leave any fields blank that aren't applicable or which you do not want as part of the SEO schema.
The social media settings connect your website to its other points of pressence on the Internet. They also facilitate attaching your branding to social media posts via Twitter Cards and Facebook OpenGraph.
None of the Tracking Scripts are included on the page unless the SEOmatic environment is set to live
production. If devMode
is enabled, the SEOmatic environment is automatically set to local
development.
Google Analytics gives you the digital analytics tools you need to analyze data from all touchpoints in one place, for a deeper understanding of the customer experience. You can then share the insights that matter with your whole organization. Learn More
If you want to include the Google Analytics script despite devMode
being enabled, you can do:
{% do seomatic.script.get('googleAnalytics').include(true) %}
The global site tag (gtag.js) is a JavaScript tagging framework and API that allows you to send event data to AdWords, DoubleClick, and Google Analytics. Instead of having to manage multiple tags for different products, you can use gtag.js and more easily benefit from the latest tracking features and integrations as they become available. Learn More
If you want to include the gtag script despite devMode
being enabled, you can do:
{% do seomatic.script.get('gtag').include(true) %}
Google Tag Manager is a tag management system that allows you to quickly and easily update tags and code snippets on your website. Once the Tag Manager snippet has been added to your website or mobile app, you can configure tags via a web-based user interface without having to alter and deploy additional code. Learn More
You can set the dataLayer
passed in to Google Tag Manager via Twig:
{% do seomatic.script.get('googleTagManager').dataLayer({
'woof': 'bark'
}) %}
If you want to include the Google Tag Manager script despite devMode
being enabled, you can do:
{% do seomatic.script.get('googleTagManager').include(true) %}
The Facebook pixel is an analytics tool that helps you measure the effectiveness of your advertising. You can use the Facebook pixel to understand the actions people are taking on your website and reach audiences you care about. Learn More
If you want to include the Facebook Pixel script despite devMode
being enabled, you can do:
{% do seomatic.script.get('facebookPixel').include(true) %}
The Plugin Settings lets you control various SEOmatic settings globally (across all sites/languages).
- Plugin name - This is the name that will be used for the plugin everywhere it is referenced in the Control Panel GUI
- Automatic Render Enabled - Controls whether SEOmatic will automatically render metadata on your pages. If you turn this off, you will need to manually render the metadata via
{{ seomatic.tag.render() }}
,{{ seomatic.link.render() }}
, etc. You can selectively disable rendering via Twig with{% do seomatic.config.renderEnabled(false)
%} - Sitemaps Enabled - Controls whether SEOmatic will automatically render frontend sitemaps for your website.
- HTTP Headers Enabled - Controls whether SEOmatic will automatically add
X-Robots-Tag
,canonical
, &Referrer-Policy
to the http response headers. - Environment - The server environment, either
live
,staging
, orlocal
. IfdevMode
is on, SEOmatic will override this setting to local Development. This setting controls whether certain things render; for instance only in thelive
production environment will Google Analytics and other tracking tags send analytics data. SEOmatic also automatically sets therobots
tag tonone
for everything but thelive
production environment. - Display Sidebar SEO Preview - Controls whether to display the Google, Twitter, and Facebook social media previews in the sidebar on entry. category, and product pages.
- devMode
<title>
prefix - If devMode is on, prefix the<title>
with this string - Control Panel
<title>
prefix - Prefix the Control Panel<title>
with this string - devMode Control Panel
<title>
prefix - If devMode is on, prefix the Control Panel<title>
with this string - Separator Character - The separator character to use for the
<title>
tag - Max SEO Title Length - The max number of characters in the <title> tag; anything beyond this will be truncated on word boundaries
- Max SEO Description Length - The max number of characters in the
meta description
tag - Site Groups define logically separate sites - If you are using Site Groups to logically separate 'sister sites', turn this on.
- Add
hreflang
Tags - Controls whether SEOmatic will automatically addhreflang
andog:locale:alternate
tags. - Generator Enabled - Controls whether SEOmatic will include the meta
generator
tag andX-Powered-By
header
If you're using a multi-environment config, you can map your environment settings using SEOmatic's config.php
something like this:
<?php
return [
'*' => [
// The public-facing name of the plugin
'pluginName' => 'SEOmatic',
// Should SEOmatic render metadata?
'renderEnabled' => true,
// Should SEOmatic render frontend sitemaps?
'sitemapsEnabled' => true,
// Should sitemaps be regenerated automatically?
'regenerateSitemapsAutomatically' => true,
// The server environment, either `live`, `staging`, or `local`
'environment' => 'live',
// Should SEOmatic display the SEO Preview sidebar?
'displayPreviewSidebar' => true,
// Should SEOmatic display the SEO Analysis sidebar?
'displayAnalysisSidebar' => true,
// If `devMode` is on, prefix the <title> with this string
'devModeTitlePrefix' => '🚧 ',
// The separator character to use for the `<title>` tag
'separatorChar' => '|',
// The max number of characters in the `<title>` tag
'maxTitleLength' => 70,
// The max number of characters in the `<meta name="description">` tag
'maxDescriptionLength' => 155,
],
'local' => [
'environment' => 'local',
],
'staging' => [
'environment' => 'staging',
],
'live' => [
'environment' => 'live',
],
];
Just copy the config.php
to your Craft config/
directory as seomatic.php
and you can configure the settings in a multi-environment friendly way. See the Craft Environments page for details, and N.B.:
The
'*'
key is required here so Craft knows to treat it as a multi-environment key, but the other keys are up to you
This is how you can make your multi-environment nomenclature to SEOmatic's. This works exactly like Craft's multi-environment config files such as general.php
and db.php
. See SEOmatic's config.php
for details.
SEOmatic allows you to restrict access to various parts of the plugin based on User Group Permissions:
- Dashboard
- Edit Global Meta
- General
- Robots
- Humans
- Ads
- Edit Content SEO
- General
- Sitemap
- Edit Site Settings
- Identity
- Creator
- Social Media
- Miscellaneous
- Edit Tracking Scripts
- Google Analytics
- Google gtag.js
- Google Tag Manager
- Facebook Pixel
- Edit Plugin Settings
SEOmatic has an SEO Settings Field that you can add to your Field Layouts. For most sites, the Field is not needed; instead set up the fields to pull from in the Content SEO settings for each Section.
Modern SEO works best if it actually reflects what is on the page, visible to the user, so pulling from your page's content will work well in most cases.
However, in some cases you may want more control over page SEO for specific entries. That's where the SEO Settings field comes in. Add it to your Section's Field Layout, and you can override specific SEO settings on a per-entry basis.
Any setting that you leave blank or empty in the SEO Settings field will just default to the Content SEO and/or Global SEO setting.
The Field settings let you control exactly what fields will appear and be visible for you or your client to override:
By default, just a few sensible settings are made visible in the Field:
Any setting left blank will just fall back on the Content SEO settings for that Section, so you can use the Field only for the exceptional cases.
You can enable every possible field to be displayed in the SEO Settings field if you like:
But it's probably best to limit it to just the things that you or your client might want to change on a per-entry basis.
If you enable an SEO Settings field in an Element Index's Table Columns, you'll see an SEO preview there as well:
You can control whether the preview will be from Google, Facebook, or Twitter in the Field Settings.
If you need to access your SEOmatic field's data directly in a template, you can do so via:
{{ entry.mySeoSettingsField.metaGlobalVars.seoTitle }}
All of the variables listed in the General Variables can be accessed in this manner.
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 %}
<article>
<h1>{{ entry.title }}</h1>
{{ entry.body }}
</article>
{% 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
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.
If you want to disable SEOmatic's automatic rendering of these tags, you can do:
{% do seomatic.link.get('alternate').include(false) %}
{% do seomatic.link.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.
If you want 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.
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.
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 = seomatic.link.create({
"rel": "amphtml",
"content": 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"
}
}
}
</script>
</amp-analytics>
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.
SEOmatic can work fully without any Twig templating code at all. However, it provides a robust API that you can tap into from your Twig templates should you desire to do so.
SEOmatic makes a global seomatic
variable available in your Twig templates that allows you to work with the SEOmatic variables and functions.
If you use Craft's built-in {% cache %}
tags, ensure that you don't have any of SEOmatic's tags (listed below) inside of them. The reason is that SEOmatic dynamically generates the tags on each request, using its own caching system for performance reasons.
When you surround any Twig code in a {% cache %}
tag, that code will only ever be executed once. On subsequent runs, the HTML result of what was inside of the {% cache %}
tag is just returned, and the Twig code inside of it is never executed.
For more information on how the {% cache %}
tag works, see the The Craft {% cache %} Tag In-Depth article.
All of the SEOmatic variables can be accessed as you would any normal Twig variable:
{{ seomatic.meta.seoTitle }}
or
{% set title = seomatic.meta.seoTitle %}
They can also be changed by passing in a value with the Twig {% do %}
syntax:
{% do seomatic.meta.seoTitle("Some Title") %}
or
{% do seomatic.meta.seoDescription("This is my description. There are many like it, but this one is mine.") %}
You can also set multiple variables at once using array syntax:
{% do seomatic.meta.setAttributes({
"seoTitle": "Some Title",
"seoDescription": "This is my description. There are many like it, but this one is mine."
})
%}
Or you can chain them together:
{% do seomatic.meta
.seoTitle("Some Title")
.seoDescription("This is my description. There are many like it, but this one is mine.")
%}
These do the same thing, so use whichever you prefer.
You can set SEOmatic variables anywhere in your templates, even in sub-templates you include
from other templates. This works because SEOmatic dynamically injects the meta tags, scripts, links, and JSON-LD into your page after the template is done rendering.
SEOmatic variables can also reference other SEOmatic variables using single-bracket syntax:
{% do seomatic.meta.seoDescription("{seomatic.meta.seoTitle}") %}
You can also reference entry
, category
, or product
Craft variables, if they are present in your template:
{% do seomatic.meta.seoTitle("{entry.title}") %}
or
{% do seomatic.meta.seoTitle("{category.title}") %}
But most of the time, you'll want to just set them like you would regular variables:
{% do seomatic.meta.seoTitle(entry.title) %}
or
{% do seomatic.meta.seoTitle(category.title) %}
...so that there is no additional Twig parsing that needs to be done.
There may be occasions where you want to output the final parsed value of an SEOmatic variable on the frontend. You can do that via seomatic.meta.parsedValue()
. For example:
{{ seomatic.meta.parsedValue('seoDescription') }}
This will output the final parsed value of the seomatic.meta.seoDescription
variable.
This parsing is done automatically by SEOmatic just before the meta information is added to your page.
The seomatic.meta
variable contains all of the meta variables that control the SEO that will be rendered on the site. They are pre-populated from your settings and content in the Control Panel, but you can change them as you see fit.
seomatic.meta.mainEntityOfPage
- the schema.org type that represents the main entity of the pageseomatic.meta.seoTitle
- the title that is used for the<title>
tagseomatic.meta.siteNamePosition
- controls where theseomatic.site.siteName
appears relative to theseomatic.meta.seoTitle
in the<title>
tag. Valid values arebefore
,after
, ornone
.seomatic.meta.seoDescription
- the description that is used for the<meta name="description">
tagseomatic.meta.seoKeywords
- the keywords that are used for the<meta name="keywords">
tag. Note that this tag is ignored by Googleseomatic.meta.seoImage
- the image URL that is used for SEO imageseomatic.meta.seoImageWidth
- the width of the SEO imageseomatic.meta.seoImageHeight
- the height of the SEO imageseomatic.meta.seoImageDescription
- a textual description of the SEO imageseomatic.meta.canonicalUrl
- the URL used for the<link rel="canonical">
tag. By default, this is set to{seomatic.helper.safeCanonicalUrl()}
or{entry.url}
/{category.url}
/{product.url}
, but you can change it as you see fit. This variable is also used to set thelink rel="canonical"
HTTP header.seomatic.meta.robots
- the setting used for the<meta name="robots">
tag that controls how bots should index your website. This variable is also used to set theX-Robots-Tag
HTTP header. Learn More
seomatic.meta.ogType
- the value used for the<meta property="og:type">
tag, such aswebsite
orarticle
seomatic.meta.ogTitle
- the value used for the<meta property="og:title">
tag. This defaults to{seomatic.meta.seoTitle}
seomatic.meta.ogSiteNamePosition
- controls where theseomatic.site.siteName
appears relative to theseomatic.meta.ogTitle
in the<meta property="og:title">
tag. Valid values arebefore
,after
, ornone
.seomatic.meta.ogDescription
- the value used for the<meta property="og:description">
tag. This defaults to{seomatic.meta.seoDescription}
seomatic.meta.ogImage
- the value used for the<meta property="og:image">
tag. This defaults to{seomatic.meta.seoImage}
seomatic.meta.ogImageWidth
- the width of the ogImage. This defaults to{seomatic.meta.seoImageWidth}
seomatic.meta.ogImageHeight
- the height of the ogImage. This defaults to{seomatic.meta.seoImageHeight}
seomatic.meta.ogImageDescription
- the value used for the<meta property="og:image:alt">
tag. This defaults to{seomatic.meta.seoImageDescription}
seomatic.meta.twitterCard
- the value used for the<meta name="twitter:card">
tag, such assummary
orsummary_large_image
seomatic.meta.twitterCreator
- the value used for the<meta name="twitter:creator">
tag. This defaults to{seomatic.site.twitterHandle}
seomatic.meta.twitterTitle
- the value used for the<meta name="twitter:title">
tag. This defaults to{seomatic.meta.seoTitle}
seomatic.meta.twitterSiteNamePosition
- controls where theseomatic.site.siteName
appears relative to theseomatic.meta.twitterTitle
in the<meta name="twitter:title">
tag. Valid values arebefore
,after
, ornone
.seomatic.meta.twitterDescription
- the value used for the<meta name="twitter:description">
tag. This defaults to{seomatic.meta.seoDescription}
seomatic.meta.twitterImage
- the value used for the<meta name="twitter:image">
tag. This defaults to{seomatic.meta.seoImage}
seomatic.meta.twitterImageWidth
- the width of the Twitter image. This defaults to{seomatic.meta.seoImageWidth}
seomatic.meta.twitterImageHeight
- the height of the Twitter image. This defaults to{seomatic.meta.seoImageHeight}
seomatic.meta.twitterImageDescription
- the value used for the<meta name="twitter:image:alt">
tag. This defaults to{seomatic.meta.seoImageDescription}
The seomatic.site
variable has site-wide settings that are available on a per-site basis for multi-site setups.
seomatic.site.siteName
- The name of the websiteseomatic.site.twitterHandle
- The site Twitter handleseomatic.site.facebookProfileId
- The site Facebook profile IDseomatic.site.facebookAppId
- The site Facebook app IDseomatic.site.googleSiteVerification
- The Google Site Verification codeseomatic.site.bingSiteVerification
- The Bing Site Verification codeseomatic.site.pinterestSiteVerification
- The Pinterest Site Verification codeseomatic.site.sameAsLinks
- Array of links for Same As... sites, indexed by the handle. So for example you could access the site Facebook URL via{{ seomatic.site.sameAsLinks["facebook"]["url"] }}
. These links are used to generate the<meta property="og:same_as">
tags, and are also used in thesameAs
property in themainEntityOfPage
JSON-LD.seomatic.site.siteLinksSearchTarget
- Google Site Links search target. Learn Moreseomatic.site.siteLinksQueryInput
- Google Site Links query input. Learn More
The seomatic.site.identity
variable is used to create JSON-LD Structured Data that can appear as Rich Snippets on Google Search Engine Results Pages (SERP). JSON-LD Structured Data helps computers understand context and relationships, and is also read by other social media sites and apps.
The seomatic.site.identity
encapsulates all of the information associated with the owner of the website.
seomatic.site.identity.siteType
- The schema.org general typeseomatic.site.identity.siteSubType
- The schema.org sub-typeseomatic.site.identity.siteSpecificType
- The schema.org specific typeseomatic.site.identity.computedType
- The computed most specific schema.org typeseomatic.site.identity.genericName
- The name of the entity that owns the websiteseomatic.site.identity.genericAlternateName
- An alternate or nickname for the entity that owns the websiteseomatic.site.identity.genericDescription
- A description of the entity that owns the websiteseomatic.site.identity.genericUrl
- A URL for the entity that owns the websiteseomatic.site.identity.genericImage
- A URL to an image or logo that represents the entity that owns the website. The image must be in JPG, PNG, or GIF format.seomatic.site.identity.genericImageWidth
- The width of the entity imageseomatic.site.identity.genericImageHeight
- The height of the entity imageseomatic.site.identity.genericImageIds
- Asset ID array for the entity imageseomatic.site.identity.genericTelephone
- The primary contact telephone number for the entity that owns the websiteseomatic.site.identity.genericEmail
- The primary contact email address for the entity that owns the websiteseomatic.site.identity.genericStreetAddress
- The street address of the entity that owns the website, e.g.: 123 Main Streetseomatic.site.identity.genericAddressLocality
- locality of the entity that owns the website, e.g.: Portchesterseomatic.site.identity.genericAddressRegion
- The region of the entity that owns the website, e.g.: New York or NYseomatic.site.identity.genericPostalCode
- The postal code of the entity that owns the website, e.g.: 14580seomatic.site.identity.genericAddressCountry
- The country in which the entity that owns the website is located, e.g.: USseomatic.site.identity.genericGeoLatitude
- The latitude of the location of the entity that owns the website, e.g.: -120.5436367seomatic.site.identity.genericGeoLongitude
- The longitude of the location of the entity that owns the website, e.g.: 80.6033588seomatic.site.identity.personGender
- Only for entities of the type Person, the gender of the personseomatic.site.identity.personBirthPlace
- Only for entities of the type Person, the place where the person was bornseomatic.site.identity.organizationDuns
- Only for entities of the type Organization, the DUNS (Dunn & Bradstreet) number of the organization that owns the websiteseomatic.site.identity.organizationFounder
- Only for entities of the type Organization, the name of the founder of the organizationseomatic.site.identity.organizationFoundingDate
- Only for entities of the type Organization, the date the organization/company/restaurant was founded in ISO 8601 date format, e.g.:2018-03-26
seomatic.site.identity.organizationFoundingLocation
- Only for entities of the type Organization, the location where the organization was foundedseomatic.site.identity.organizationContactPoints
- Only for entities of the type Organization, an array of contact points for the organization. Learn Moreseomatic.site.identity.corporationTickerSymbol
- Only for entities of the type Corporation, the exchange ticker symbol of the corporationseomatic.site.identity.localBusinessPriceRange
- Only for entities of the type LocalBusiness, the approximate price range of the goods or services offered by this local businessseomatic.site.identity.localBusinessOpeningHours
- Only for entities of the type LocalBusiness, an array of the opening hours for this local business. [Learn More][https://developers.google.com/search/docs/data-types/local-business]seomatic.site.identity.restaurantServesCuisine
- Only for entities of the type Food Establishment, the primary type of cuisine that the food establishment servesseomatic.site.identity.restaurantMenuUrl
- Only for entities of the type Food Establishment, a URL to the food establishment's menuseomatic.site.identity.restaurantReservationsUrl
- Only for entities of the type Food Establishment, a URL to the food establishment's reservations page
The seomatic.site.creator
variable is used to create JSON-LD Structured Data that can appear as Rich Snippets on Google Search Engine Results Pages (SERP). JSON-LD Structured Data helps computers understand context and relationships, and is also read by other social media sites and apps.
The seomatic.site.creator
encapsulates all of the information associated with the creator of the website. This information is also used in the humans.txt
page
seomatic.site.creator.siteType
- The schema.org general typeseomatic.site.creator.siteSubType
- The schema.org sub-typeseomatic.site.creator.siteSpecificType
- The schema.org specific typeseomatic.site.creator.computedType
- The computed most specific schema.org typeseomatic.site.creator.genericName
- The name of the entity that created the websiteseomatic.site.creator.genericAlternateName
- An alternate or nickname for the entity that created the websiteseomatic.site.creator.genericDescription
- A description of the entity that created the websiteseomatic.site.creator.genericUrl
- A URL for the entity that created the websiteseomatic.site.creator.genericImage
- A URL to an image or logo that represents the entity that created the website. The image must be in JPG, PNG, or GIF format.seomatic.site.creator.genericImageWidth
- The width of the entity imageseomatic.site.creator.genericImageHeight
- The height of the entity imageseomatic.site.creator.genericImageIds
- Asset ID array for the entity imageseomatic.site.creator.genericTelephone
- The primary contact telephone number for the entity that created the websiteseomatic.site.creator.genericEmail
- The primary contact email address for the entity that created the websiteseomatic.site.creator.genericStreetAddress
- The street address of the entity that created the website, e.g.: 123 Main Streetseomatic.site.creator.genericAddressLocality
- locality of the entity that created the website, e.g.: Portchesterseomatic.site.creator.genericAddressRegion
- The region of the entity that created the website, e.g.: New York or NYseomatic.site.creator.genericPostalCode
- The postal code of the entity that created the website, e.g.: 14580seomatic.site.creator.genericAddressCountry
- The country in which the entity that created the website is located, e.g.: USseomatic.site.creator.genericGeoLatitude
- The latitude of the location of the entity that created the website, e.g.: -120.5436367seomatic.site.creator.genericGeoLongitude
- The longitude of the location of the entity that created the website, e.g.: 80.6033588seomatic.site.creator.personGender
- Only for entities of the type Person, the gender of the personseomatic.site.creator.personBirthPlace
- Only for entities of the type Person, the place where the person was bornseomatic.site.creator.organizationDuns
- Only for entities of the type Organization, the DUNS (Dunn & Bradstreet) number of the organization that created the websiteseomatic.site.creator.organizationFounder
- Only for entities of the type Organization, the name of the founder of the organizationseomatic.site.creator.organizationFoundingDate
- Only for entities of the type Organization, the date the organization/company/restaurant was founded in ISO 8601 date format, e.g.:2018-03-26
seomatic.site.creator.organizationFoundingLocation
- Only for entities of the type Organization, the location where the organization was foundedseomatic.site.creator.organizationContactPoints
- Only for entities of the type Organization, an array of contact points for the organization. Learn Moreseomatic.site.creator.corporationTickerSymbol
- Only for entities of the type Corporation, the exchange ticker symbol of the corporationseomatic.site.creator.localBusinessPriceRange
- Only for entities of the type LocalBusiness, the approximate price range of the goods or services offered by this local businessseomatic.site.creator.localBusinessOpeningHours
- Only for entities of the type LocalBusiness, an array of the opening hours for this local business. [Learn More][https://developers.google.com/search/docs/data-types/local-business]seomatic.site.creator.restaurantServesCuisine
- Only for entities of the type Food Establishment, the primary type of cuisine that the food establishment servesseomatic.site.creator.restaurantMenuUrl
- Only for entities of the type Food Establishment, a URL to the food establishment's menuseomatic.site.creator.restaurantReservationsUrl
- Only for entities of the type Food Establishment, a URL to the food establishment's reservations page
The seomatic.config
variables are the global plugin configuration variables set in the config.php
file. You can copy the config.php
file to the Craft config/
directory as seomatic.php
to change them in a multi-environment friendly way.
seomatic.config.pluginName
- The public-facing name of the pluginseomatic.config.renderEnabled
- Should SEOmatic render metadata?seomatic.config.environment
- The server environment, eitherlive
,staging
, orlocal
seomatic.config.displayPreviewSidebar
- Should SEOmatic display the SEO Preview sidebar?seomatic.config.displayAnalysisSidebar
- Should SEOmatic display the SEO Analysis sidebar?seomatic.config.devModeTitlePrefix
- IfdevMode
is on, prefix the<title>
with this stringseomatic.config.separatorChar
- The separator character to use for the<title>
tagseomatic.config.maxTitleLength
- The max number of characters in the<title>
tagseomatic.config.maxDescriptionLength
- The max number of characters in the<meta name="description">
tag
seomatic.helper.paginate(PAGEINFO)
- Given thePAGEINFO
variable from the{% paginate %}
tag as described here, this will properly set thecanonicalUrl
, as well as adding the<link rel='prev'>
and<link rel='next'>
tags for you.seomatic.helper.truncate(TEXT, LENGTH, SUBSTR)
- Truncates theTEXT
to a givenLENGTH
. IfSUBSTR
is provided, and truncating occurs, the string is further truncated so that the substring may be appended without exceeding the desired length.seomatic.helper.truncateOnWord(TEXT, LENGTH, SUBSTR)
- Truncates theTEXT
to a givenLENGTH
, while ensuring that it does not split words. IfSUBSTR
is provided, and truncating occurs, the string is further truncated so that the substring may be appended without exceeding the desired length.seomatic.helper.getLocalizedUrls(URI, SITE_ID)
- Return a list of localized URLs for a givenURI
that are in theSITE_ID
site's group. BothURI
andSITE_ID
are optional, and will use the current request'sURI
and the current site'sSITE_ID
if omitted.seomatic.helper.loadMetadataForUri(URI, SITE_ID)
- Load the appropriate meta containers for the givenURI
and optionalSITE_ID
seomatic.helper.sitemapIndexForSiteId(SITE_ID)
- Get the URL to theSITE_ID
s sitemap indexseomatic.helper.extractTextFromField(FIELD)
- Extract plain text from a PlainText, Redactor, CKEdtior, Tags, Matrix, or Neo fieldseomatic.helper.extractKeywords(TEXT, LIMIT)
- Extract up toLIMIT
most important keywords fromTEXT
seomatic.helper.extractSummary(TEXT)
- Extract the most important 3 sentences fromTEXT
seomatic.helper.socialTransform(ASSET, TRANSFORMNAME)
- Transform theASSET
(either an Asset or an Asset ID) for social media sites inTRANSFORMNAME
; valid values arebase
,facebook
,twitter-summary
, andtwitter-large
seomatic.helper.seoFileLink(FILE_URL, ROBOTS, CANONICAL, INLINE)
- Generates a link to a local or remote file that allows you to set theX-Robots-Tag
header viaROBOTS
(defaults toall
) andLink
canonical header viaCANONICAL
(defaults to''
) as per Advanced rel="canonical" HTTP Headers.INLINE
controls whether the file will be displayed inline or downloaded. If any values are empty''
, the headers will not be included.
All of the SEOmatic tags, links, scripts, title, and JSON-LD are meta objects that have their values set from the seomatic.meta
variables.
These meta objects know what properties they should have, and can self-validate. If devMode
is on, you can check the Yii2 Debug Toolbar's Log to see any validation warnings or errors with your tags.
All of SEOmatic's meta objects are stored in containers, and they can be accessed and manipulated directly. You can even dynamically create new tags via Twig at template render time.
All of the meta object (tags, scripts, links, title, and JSON-LD) have the same API to make it easy to use.
{% set descriptionTag = seomatic.tag.get("description") %}
...will return the <meta name="description">
meta object to you in descriptionTag
.
You can access meta object properties just like you can any Twig variable:
{{ descriptionTag.content }}
or
{% set myContent = seomatic.meta.seoTitle %}
They can also be changed by passing in a value with the Twig {% do %}
syntax:
{% do descriptionTag.content("Some description") %}
All meta objects also have an include
property that determines whether or not they should be included on your web page:
{% do descriptionTag.include(false) %}
You could also chain this together in a single line:
{% do seomatic.tag.get("description").include(false) %}
And you can set multiple attributes at once using an array syntax:
{% do seomatic.tag.get("description").setAttributes({
"content": "Some Description",
"include": false
})
%}
Which is the same as doing:
{% do seomatic.tag.get("description")
.content("Some Description")
.include(false)
%}
So use whatever you like better.
To create a new meta object, you pass in a key:value array of the attributes to use when creating it:
{% set linkTag = seomatic.link.create({
"rel": "canonical",
"content": "https://nystudio107.com"
})
%}
By default, newly created meta objects are added to the appropriate meta container, so they will be rendered on the page. Should you wish to create a meta object but not have it added to a container, you can pass in an optional false
parameter:
{% set linkTag = seomatic.link.create({
"rel": "canonical",
"content": "https://nystudio107.com"
}, false)
%}
All meta objects can self-validate:
{% set myJsonLd = seomatic.jsonLd.create({
'type': 'Article',
'name': 'Some Blog',
'url': 'woopsie',
}) %}
{% if myJsonLd.validate() %}
<p>Valid!</p>
{% else %}
<ul>
{% for param,errors in myJsonLd.errors %}
<li>
{{ param ~ " " }}
<ul>
{% for error in errors %}
<li>
{{ error ~ " " }}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endif %}
This will output:
- url
- Must be one of these types: URL
Which tells you that the url
parameter is invalid. The default validation just ensures that all of the properties are correct.
You can also set the scenario to display properties that Google requires/recommends:
{% set myJsonLd = seomatic.jsonLd.create({
'type': 'Article',
'name': 'Some Blog',
'url': 'woopsie',
}) %}
{% do myJsonLd.setScenario('google') %}
{% if myJsonLd.validate() %}
<p>Valid!</p>
{% else %}
<ul>
{% for param,errors in myJsonLd.errors %}
<li>
{{ param ~ " " }}
<ul>
{% for error in errors %}
<li>
{{ error ~ " " }}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endif %}
This will output:
- url
- Must be one of these types: URL
- image
- This property is recommended by Google.
- author
- This property is required by Google.
- datePublished
- This property is required by Google.
- headline
- This property is required by Google.
- publisher
- This property is required by Google.
- mainEntityOfPage
- This property is recommended by Google.
- dateModified
- This property is recommended by Google.
If the website has devMode
on, all of the meta objects are automatically validated as they are rendered, with the results displayed in the Yii Debug Toolbar. The Yii Debug Toolbar can be enabled in your account settings page.
seomatic.jsonLd.get(META_HANDLE)
Returns the JSON-LD meta object of the handleMETA_HANDLE
ornull
if it is not foundseomatic.jsonLd.create()
Creates a JSON-LD meta object from an array of key/value properties. Thetype
can be any of the Schema.org types.seomatic.jsonLd.add(META_OBJECT)
Adds theMETA_OBJECT
to the JSON-LD container to be renderedseomatic.jsonLd.render()
Renders all of the JSON-LD meta objects to your template. This is only needed if you have turned off Automatic Render in Plugin Settingsseomatic.jsonLd.container()
Returns the container that holds an array of all of the JSON-LD meta objects
Create a new Article JSON-LD meta object:
{% set myJsonLd = seomatic.jsonLd.create({
'type': 'Article',
'name': 'Some Blog',
'url': 'https://nystudio107.com/blog',
}) %}
Get the existing MainEntityOfPage as set in the Global SEO or Content SEO Control Panel section to modify it (schema.org: mainEntityOfPage):
{% set mainEntity = seomatic.jsonLd.get('mainEntityOfPage') %}
If you want to add something to the existing MainEntityOfPage (in this case an Offer), you can do it like this:
{% set mainEntity = seomatic.jsonLd.get('mainEntityOfPage') %}
{% set offersJsonLd = seomatic.jsonLd.create({
'type': 'Offer',
'name': 'Some prop',
'url': 'Some url',
}, false) %}
{% do mainEntity.offers(offerJsonLd) %}
The , false
parameter tells it to create the JSON-LD object, but to not automatically add it to the JSON-LD container. We do this because we don't want it rendered on its own, we want it as part of the existing mainEntityOfPage
JSON-LD object.
Get the existing BreadcrumbList as generated automatically by SEOmatic to modify them (schema.org: BreadcrumbList):
{% set crumbs = seomatic.jsonLd.get('breadcrumbList') %}
Display the breadcrumbs on the page:
{% set crumbList = seomatic.jsonLd.get('breadcrumbList').itemListElement %}
{% for crumb in crumbList %}
<a href="{{ crumb.item['@id'] }}">{{ crumb.item['name'] }}</a>
{% if not loop.last %}»{% endif %}
{% endfor %}
To entirely replace the existing BreadcrumbList on a page:
{% set crumbList = seomatic.jsonLd.create({
'type': 'BreadcrumbList',
'name': 'Breadcrumbs',
'description': 'Breadcrumbs list',
'itemListElement': [
{
'type': 'ListItem',
'item': {
'@id': 'http://example.com/',
'name': 'Homepage'
},
},
{
'type': 'ListItem',
'item': {
'@id': 'http://example.com/blog/',
'name': 'Our blog'
},
},
{
'type': 'ListItem',
'item': {
'@id': 'http://example.com/blog/tech',
'name': 'Technology blogs'
},
},
]
}) %}
Get the existing Identity as set in the Site Settings Control Panel section to modify it:
{% set identity = seomatic.jsonLd.get('identity') %}
Let's say you want to add a Brand to the Identity, you'd do this:
{% set identity = seomatic.jsonLd.get('identity') %}
{% set brand = seomatic.jsonLd.create({
'type': 'Brand',
'name': 'Some prop',
'url': 'Some url',
}, false) %}
{% do identity.brand(brand) %}
The , false
parameter tells it to create the JSON-LD object, but to not automatically add it to the JSON-LD container. We do this because we don't want it rendered on its own, we want it as part of the existing mainEntityOfPage
JSON-LD object.
Get the existing Creator as set in the Site Settings Control Panel section to modify it:
{% set identity = seomatic.jsonLd.get('creator') %}
seomatic.link.get(META_HANDLE)
Returns the Link meta object of the handleMETA_HANDLE
ornull
if it is not foundseomatic.link.create(CONFIG_ARRAY)
Creates a Link meta object from an array of key/value propertiesseomatic.link.add(META_OBJECT)
Adds theMETA_OBJECT
to the Link container to be renderedseomatic.link.render()
Renders all of the Link meta objects to your template. This is only needed if you have turned off Automatic Render in Plugin Settingsseomatic.link.container()
Returns the container that holds an array of all of the Link meta objects
Change the <link rel="canonical">
:
{% do seomatic.link.get("canonical").href("https://nystudio107.com") %}
Note that you can achieve the same result with:
{% do seomatic.meta.canonicalUrl("https://nystudio107.com") %}
...since the canonicalUrl
populates the <link rel="canonical">
Link meta object
seomatic.script.get(META_HANDLE)
Returns the Script meta object of the handleMETA_HANDLE
ornull
if it is not foundseomatic.script.create()
Creates a Script meta object from an array of key/value propertiesseomatic.script.add(META_OBJECT)
Adds theMETA_OBJECT
to the Script container to be renderedseomatic.script.render()
Renders all of the Script meta objects to your template. This is only needed if you have turned off Automatic Render in Plugin Settingsseomatic.script.container()
Returns the container that holds an array of all of the Script meta objects
Don't include the Google Analytics script on the page:
{% do seomatic.script.get("googleAnalytics").include(false) %}
seomatic.tag.get(META_HANDLE)
Returns the Tag meta object of the handleMETA_HANDLE
ornull
if it is not foundseomatic.tag.create()
Creates a Tag meta object from an array of key/value propertiesseomatic.tag.add(META_OBJECT)
Adds theMETA_OBJECT
to the Tag container to be renderedseomatic.tag.render()
Renders all of the Tag meta objects to your template. This is only needed if you have turned off Automatic Render in Plugin Settingsseomatic.tag.container()
Returns the container that holds an array of all of the Tag meta objects
Change the <meta name="twitter:title">
:
{% do seomatic.tag.get("twitter:title").content("Hello, world") %}
Note that you can achieve the same result with:
{% do seomatic.meta.twitterTitle("Hello, world") %}
...since the twitterTitle
populates the <meta name="twitter:title">
Tag meta object by default.
Let's say you didn't want Google et al to index a particular page or under certain conditions. You could do this:
{% do seomatic.tag.get("robots").content("none") %}
Note that you can achieve the same result with:
{% do seomatic.meta.robots("none") %}
...since the robots
populates the <meta name="robots">
Tag meta object by default.
seomatic.title.get(META_HANDLE)
Returns the Title meta object of the handleMETA_HANDLE
ornull
if it is not foundseomatic.title.create()
Creates a Title meta object from an array of key/value propertiesseomatic.title.add(META_OBJECT)
Adds theMETA_OBJECT
to the Title container to be renderedseomatic.title.render()
Renders Title meta object to your template. This is only needed if you have turned off Automatic Render in Plugin Settingsseomatic.title.container()
Returns the container that holds an array with the Title meta object in it
Change the <title>
:
{% do seomatic.title.get("title").content("My page title") %}
Note that you can achieve the same result with:
{% do seomatic.meta.seoTitle("My page title") %}
...since the seoTitle
populates the <title">
Title meta object
Normally you don't need to work with meta containers directly, but SEOmatic gives you access to them if you need to.
You can get the meta container for each type of meta object by doing:
{% set jsonLdContainer = seomatic.jsonLd.container() %}
{% set linkContainer = seomatic.link.container() %}
{% set scriptContainer = seomatic.script.container() %}
{% set tagContainer = seomatic.tag.container() %}
{% set titleContainer = seomatic.title.container() %}
Then you can do things like tell an entire container to not render:
{% set scriptContainer = seomatic.script.container() %}
{% do scriptContainer.include(false) %}
or just:
{% do seomatic.script.container().include(false) %}
Containers are also cached. Typically SEOmatic manages this cache for you, but should you wish to invalidate the cache manually, you can do so via:
{% set scriptContainer = seomatic.script.container() %}
{% do scriptContainer.clearCache(true) %}
or just:
{% do seomatic.script.container().clearCache(true) %}
SEOmatic supports the standard config.php
multi-environment friendly config file for the plugin settings. Just copy the config.php
to your Craft config/
directory as seomatic.php
and you can configure the settings in a multi-environment friendly way.
These are the same settings that are configured in the Plugin Settings in the Control Panel.
The directory vendor/nystudio107/seomatic/src/seomatic-config
contains a number of files that are used when initially configuring SEOmatic.
You can copy this entire directory to your Craft config/
directory, and customize the files to your heart's content. SEOmatic will first look in the config/
directory for any given file, and then fall back on its own internal seomatic-config
files.
Note that these files are only used when initially creating a meta bundle. That is, whenever the plugin is installed, or new Section, Category Groups, or Commerce Product Types are created. Once meta bundles have been created, changing the settings in the file will have no effect.
You can bump the Bundle.php
's bundleVersion
setting if you want it to re-read your config settings.
SEOmatic allows you to fetch the meta information for any page via a controller API endpoint, so you can render the meta data via a frontend framework like VueJS or React.
To get all of the meta containers for a given URI, the controller action is:
/actions/seomatic/meta-container/all-meta-containers/?uri=/
...where uri
is the path to obtain the meta information from.
This will return to you an array of meta containers, with the render-ready meta tags in each:
{
"MetaTitleContainer": "<title>[devMode] Craft3 | Homepage</title>",
"MetaTagContainer": "<meta name=\"generator\" content=\"SEOmatic\"><meta name=\"referrer\" content=\"no-referrer-when-downgrade\"><meta name=\"robots\" content=\"all\">",
"MetaLinkContainer": "<link href=\"http://craft3.test/\" rel=\"canonical\"><link type=\"text/plain\" href=\"/humans.txt\" rel=\"author\"><link href=\"http://craft3.test/\" rel=\"alternate\" hreflang=\"es\">",
"MetaScriptContainer": "",
"MetaJsonLdContainer": "<script type=\"application/ld+json\">{\"@context\":\"http://schema.org\",\"@type\":\"WebPage\",\"image\":{\"@type\":\"ImageObject\",\"height\":\"804\",\"width\":\"1200\"},\"inLanguage\":\"en-us\",\"mainEntityOfPage\":\"http://craft3.test/\",\"name\":\"Homepage\",\"url\":\"http://craft3.test/\"}</script><script type=\"application/ld+json\">{\"@context\":\"http://schema.org\",\"@type\":\"BreadcrumbList\",\"description\":\"Breadcrumbs list\",\"itemListElement\":[{\"@type\":\"ListItem\",\"item\":{\"@id\":\"http://craft3.test/\",\"name\":\"Homepage\"},\"position\":1}],\"name\":\"Breadcrumbs\"}</script>"
}
If you need to request a URI from a specific site in a multi-site setup, you can do that with the optional siteId=SITE_ID
parameter:
/actions/seomatic/meta-container/all-meta-containers/?uri=/&siteId=2
Should you wish to have the items in the meta containers return as an array of data instead, you can do that with the optional asArray=true
parameter:
/actions/seomatic/meta-container/all-meta-containers/?uri=/&asArray=true
Which will return the data in array form:
{
"MetaTitleContainer": {
"title": {
"title": "[devMode] Craft3 | Homepage"
}
},
"MetaTagContainer": {
"generator": {
"content": "SEOmatic",
"name": "generator"
},
"referrer": {
"content": "no-referrer-when-downgrade",
"name": "referrer"
},
"robots": {
"content": "all",
"name": "robots"
}
},
"MetaLinkContainer": {
"canonical": {
"href": "http://craft3.test/",
"rel": "canonical"
},
"author": {
"href": "/humans.txt",
"rel": "author",
"type": "text/plain"
},
"alternate": {
"href": "http://craft3.test/",
"hreflang": "es",
"rel": "alternate"
}
},
"MetaScriptContainer": [],
"MetaJsonLdContainer": {
"WebPage": {
"@context": "http://schema.org",
"@type": "WebPage",
"image": {
"@type": "ImageObject",
"height": "804",
"width": "1200"
},
"inLanguage": "en-us",
"mainEntityOfPage": "http://craft3.test/",
"name": "Homepage",
"url": "http://craft3.test/"
},
"BreadcrumbList": {
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"description": "Breadcrumbs list",
"itemListElement": [
{
"@type": "ListItem",
"item": {
"@id": "http://craft3.test/",
"name": "Homepage"
},
"position": 1
}
],
"name": "Breadcrumbs"
}
}
}
You can also request individual meta containers.
Title container:
/actions/seomatic/meta-container/meta-title-container/?uri=/
...will return just the Title container:
{
"MetaTitleContainer": "<title>[devMode] Craft3 | Homepage</title>"
}
Tag container:
/actions/seomatic/meta-container/meta-tag-container/?uri=/
...will return just the Tag container:
{
"MetaTagContainer": "<meta name=\"generator\" content=\"SEOmatic\"><meta name=\"referrer\" content=\"no-referrer-when-downgrade\"><meta name=\"robots\" content=\"all\">"
}
Script container:
/actions/seomatic/meta-container/meta-script-container/?uri=/
...will return just the Script container:
{
"MetaScriptContainer": ""
}
Link container:
/actions/seomatic/meta-container/meta-link-container/?uri=/
...will return just the Link container:
{
"MetaLinkContainer": "<link href=\"http://craft3.test/\" rel=\"canonical\"><link type=\"text/plain\" href=\"/humans.txt\" rel=\"author\"><link href=\"http://craft3.test/\" rel=\"alternate\" hreflang=\"es\">"
}
JSON-LD container:
/actions/seomatic/meta-container/meta-json-ld-container/?uri=/
...will return just the JSON-LD container:
{
"MetaJsonLdContainer": "<script type=\"application/ld+json\">{\"@context\":\"http://schema.org\",\"@type\":\"WebPage\",\"image\":{\"@type\":\"ImageObject\",\"height\":\"804\",\"width\":\"1200\"},\"inLanguage\":\"en-us\",\"mainEntityOfPage\":\"http://craft3.test/\",\"name\":\"Homepage\",\"url\":\"http://craft3.test/\"}</script><script type=\"application/ld+json\">{\"@context\":\"http://schema.org\",\"@type\":\"BreadcrumbList\",\"description\":\"Breadcrumbs list\",\"itemListElement\":[{\"@type\":\"ListItem\",\"item\":{\"@id\":\"http://craft3.test/\",\"name\":\"Homepage\"},\"position\":1}],\"name\":\"Breadcrumbs\"}</script>"
}
All of the individual container controller API endpoints also accept the &asArray=true
parameter if you'd like the data in array form.
To get a key/value array of a given Schema.org type:
/actions/seomatic/json-ld/get-type?schemaType=Article
To get a decomposed version of a given Schema.org type, with the properties grouped by each inherited type:
/actions/seomatic/json-ld/get-decomposed-type?schemaType=Article
To get a hierarchical array of all of the schema types:
/actions/seomatic/json-ld/get-type-array?path=Article
You can narrow this down to a specific sub-type list by passing in a path
of schema types delimited by a .
:
/actions/seomatic/json-ld/get-type-array?path=CreativeWork.Article
...this would output all of the sub-types of Article
:
{
"AdvertiserContentArticle": "AdvertiserContentArticle",
"NewsArticle": {
"AnalysisNewsArticle": "AnalysisNewsArticle",
"BackgroundNewsArticle": "BackgroundNewsArticle",
"OpinionNewsArticle": "OpinionNewsArticle",
"ReportageNewsArticle": "ReportageNewsArticle",
"ReviewNewsArticle": "ReviewNewsArticle"
},
"Report": "Report",
"SatiricalArticle": "SatiricalArticle",
"ScholarlyArticle": {
"MedicalScholarlyArticle": "MedicalScholarlyArticle"
},
"SocialMediaPosting": {
"BlogPosting": {
"LiveBlogPosting": "LiveBlogPosting"
},
"DiscussionForumPosting": "DiscussionForumPosting"
},
"TechArticle": {
"APIReference": "APIReference"
}
}
Some things to do, and ideas for potential features:
- Content Analytics - Add content analytics, potentially in the "Pro" edition
Brought to you by nystudio107