SkillAgentSearch skills...

Seomate

SEO, mate! It's important. That's why SEOMate provides the tools you need to craft all the meta tags, sitemaps and JSON-LD microdata you need - in one highly configurable, open and friendly package - with a super-light footprint.

Install / Use

/learn @vaersaagod/Seomate
About this skill

Quality Score

0/100

Category

Marketing

Supported Platforms

Universal

README

SEOMate plugin for Craft CMS

SEO, mate! It's important. That's why SEOMate provides the tools you need to craft all the meta tags, sitemaps and JSON-LD microdata you need - in one highly configurable, open and friendly package - with a super-light footprint.

SEOMate aims to do less! Unlike other SEO plugins for Craft, there are no control panel settings or fieldtypes. Instead, you configure everything from the plugin's config file, which makes it easy and quick to set up, bootstrap and version control your configuration. All the data is pulled from native Craft fields, which makes for less maintenance over time, and keeps you in control of your data.

Additionally, SEOMate adds a super-awesome SEO/social media preview to your Control Panel. The SEO preview taps into Craft's native Preview Targets, giving your clients a nice and familiar interface for previewing how their content will appear on Google, Facebook and Twitter.

Screenshot

Requirements

This plugin requires Craft CMS 5.0.0 or later.

Installation

To install the plugin, either install it from the plugin store, or follow these instructions:

  1. Install with composer via composer require vaersaagod/seomate from your project directory.
  2. Install the plugin in the Craft Control Panel under Settings → Plugins, or from the command line via ./craft install/plugin seomate.
  3. For SEOMate to do anything, you need to configure it. But first, continue reading!

SEOMate Overview

SEOMate focuses on providing developers with the tools they need to craft their site's SEO in three main areas; meta data, sitemaps, and JSON-LD microdata.

Meta data

SEOMate doesn't provide any custom field types for entering meta data. Instead, you use native field types that come with Craft, and just tell SEOMate which fields to use.

You do this by configuring field profiles for the different field setups in your site. Sections and category groups can be mapped to these profiles, or the desired profile can be set at the template level.

The key config settings for meta data is fieldProfiles, profileMap, defaultProfile, defaultMeta and additionalMeta. Refer to the "Adding meta data" section on how to include the meta data in your page, and how to (optionally) override it at the template level.

Sitemaps

SEOMate lets you create completely configuration based sitemaps for all your content. The sitemaps are automatically updated with new elements, and will automatically be split into multiple sitemaps for scalability.

To enable sitemaps, set the sitemapEnabled config setting to true and configure the contents of your sitemaps with sitemapConfig. Refer to the "Enabling sitemaps" section on how to enable and set up your sitemaps.

JSON-LD

SEOMate provides a thin wrapper around the excellent spatie/schema-org package used for generating JSON-LD data structures. SEOMate exposes the craft.schema template variable, that directly ties into the fluent Schema API.

This method uses the exact same approach and signature as Rias' Schema plugin. If you're only looking for a way to output JSON-LD, we suggest you use that plugin instead.

SEO preview

SEOMate provides a fancy "SEO Preview" preview target, for any and all elements with URLs, featuring photo realistic approximations of how your content will appear in Google SERPs, or when shared on Facebook, Twitter/X and LinkedIn.

img.png

If you don't like the SEO preview, or if you'd like it to only appear for entries in specific sections, check out the previewEnabled config setting.

Things that SEOMate doesn't do...

So much!


Adding meta data

Out of the box, SEOMate doesn't add anything to your markup. To get started, add {% hook 'seomateMeta' %} to the <head> of your layout. Then, if you haven't already, create a config file named seomate.php in your config folder alongside your other Craft config files. This file can use multi-environment configs, exactly the same as any other config file in Craft, but in the following examples we'll skip that part to keep things a bit more tidy.

All the config settings are documented in the Configuring section, and there are quite a few! But to get you going, these are some fundamental concepts:

Field profiles

A field profile in SEOMate is, essentially, a mapping of metadata attributes to the fields that SEOMate should look at for those attributes' metadata values.

To get started, create a profile called "standard" in fieldProfiles, and set that profile as the default field profile using the defaultProfile setting:

<?php

return [
    'defaultProfile' => 'standard',
    
    'fieldProfiles' => [
        'standard' => [
            'title' => ['seoTitle', 'heading', 'title'],
            'description' => ['seoDescription', 'summary'],
            'image' => ['seoImage', 'mainImage']
        ]
    ],
];

The above tells SEOMate to use the field profile standard to get element metadata from, as a default. So, everytime a page template that has an element (i.e. entry, category or product) is loaded, SEOMate will start by checking if that element has a field named seoTitle, and that this field has a value that can be used for the title meta tag. If a field named seoTitle does not exist – or if it's empty – SEOMate continues to check if there is a field named heading, and does the same thing. If heading is empty, it checks for title.
And so on, for every key in the field profile.

💡 In addition to field handles, field profiles can also contain functions (i.e. closures), and/or
Twig object templates. For documentation and examples for closures and object templates,
see the fieldProfiles setting!

Mapping different field profiles to elements

Now, let's say we have a section with handle news that has a slightly different field setup than our other sections, so for entries in that section we want to pull data from some other fields. We'll add another field profile to fieldProfiles, and make a mapping between the profile and the section handle in profileMap:

<?php

return [
    'defaultProfile' => 'standard',
    
    'fieldProfiles' => [
        'standard' => [
            'title' => ['seoTitle', 'heading', 'title'],
            'description' => ['seoDescription', 'summary'],
            'image' => ['seoImage', 'mainImage']
        ],
        'newsprofile' => [
            'title' => ['seoTitle', 'heading', 'title'],
            'og:title' => ['ogSeo.title', 'ogTitle', 'heading', 'title'],
            'description' => ['seoDescription', 'newsExcerpt', 'introText'],
            'image' => ['seoImage', 'heroImage', 'newsBlocks.image:image']
            'og:image' => ['ogSeo.image', 'ogImage', 'heroImage', 'newsBlocks.image:image']
            'twitter:image' => ['twitterImage', 'heroImage', 'newsBlocks.image:image']
        ]
    ],
    
    'profileMap' => [
        'news' => 'newsprofile',
    ],    
];

The mapping between the "news" section and the profile is simple enough: the key in profileMap can be the handle for a section, entry type, category group, or Commerce product type, and the value should be the key for the profile in fieldProfiles that you want to use for matching elements.

In this profile we also we have also used a couple of other SEOMate features.

First, notice that we have chosen to specify a field profile for og:title, og:image and twitter:image that we didn't have in the default profile. By default, the autofillMap defines that if no value are set for og:title and twitter:title, we want to autofill those meta tags with the value from title. So in the standard profile, those values will be autofilled, while in the newsprofile we choose to customize some of them.

Secondly, we're using a nested object syntax for ogSeo.title and ogSeo.image which could for instance be used if you have a Content Block field (new in Craft 5.8) with values. Or any other field type that returns a nested object. It goes as deep as you want, someField.withAnObject.that.has.a.deep.structure.

Thirdly, notice that we can specify to pull a value from a Matrix subfield by using the syntax matrixFieldHandle.blockTypeHandle:subFieldHandle.

Profile map specificity

In some cases there might be a need to create more specific field profile mappings. For example, you might have a section with the handle news and a category group with the handle news, and you need their elements to use different profiles. This can be achieved by using prefixes section: and/or categoryGroup:, e.g.

'profileMap' => [
   'section:news' => 'newsprofile', // Will match entries in a section "news"
   'categoryGroup:news' => 'newscategoryprofile', // Will match categories in a group "news"
],

Another use case for specific field profiles is if you need a certain entry type to use a specific profile, in which case the entryType: prefix is the ticket:

'profileMap' => [
   'section:news' => 'newsprofile', // Will match entries in a section "news"
   'categoryGroup:news' => 'newscategoryprofile', // Will match categories in a group "news"
   'pages' => 'pagesprofile',
   'entryType:listPage' => 'listpageprofile', // Will match entries with an entry type "listPage"
],

The specific field profiles (i.e. the ones using the {sourceType}: pr

Related Skills

View on GitHub
GitHub Stars43
CategoryMarketing
Updated13d ago
Forks8

Languages

PHP

Security Score

95/100

Audited on Mar 16, 2026

No findings