{"id":42162029,"url":"https://github.com/vaersaagod/seomate","last_synced_at":"2026-01-26T20:25:39.477Z","repository":{"id":34775685,"uuid":"183601455","full_name":"vaersaagod/seomate","owner":"vaersaagod","description":"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.","archived":false,"fork":false,"pushed_at":"2025-07-02T21:30:13.000Z","size":1022,"stargazers_count":39,"open_issues_count":3,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-10-07T00:32:13.340Z","etag":null,"topics":["craft-plugin","craft3","craftcms","json-ld","metadata","schema-org","seo","sitemaps"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vaersaagod.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-26T09:37:22.000Z","updated_at":"2025-10-03T22:23:47.000Z","dependencies_parsed_at":"2022-08-08T02:00:37.123Z","dependency_job_id":"bd0be419-b838-4e48-a360-b2530dc29812","html_url":"https://github.com/vaersaagod/seomate","commit_stats":{"total_commits":84,"total_committers":8,"mean_commits":10.5,"dds":0.5476190476190477,"last_synced_commit":"d5f4352fdcbb12930f65588a62e80f5f82f48308"},"previous_names":[],"tags_count":64,"template":false,"template_full_name":null,"purl":"pkg:github/vaersaagod/seomate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaersaagod%2Fseomate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaersaagod%2Fseomate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaersaagod%2Fseomate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaersaagod%2Fseomate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vaersaagod","download_url":"https://codeload.github.com/vaersaagod/seomate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaersaagod%2Fseomate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28787221,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T13:55:28.044Z","status":"ssl_error","status_checked_at":"2026-01-26T13:55:26.068Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["craft-plugin","craft3","craftcms","json-ld","metadata","schema-org","seo","sitemaps"],"created_at":"2026-01-26T20:25:38.580Z","updated_at":"2026-01-26T20:25:39.462Z","avatar_url":"https://github.com/vaersaagod.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"SEOMate plugin for Craft CMS\n===\n\nSEO, mate! It's important. That's why SEOMate provides the tools you need to craft\nall the meta tags, sitemaps and JSON-LD microdata you need - in one highly configurable,\nopen and friendly package - with a super-light footprint. \n\nSEOMate aims to do less! Unlike other SEO plugins for Craft, there are no control panel \nsettings or fieldtypes. Instead, you configure everything from the plugin's \nconfig file, which makes it easy and quick to set up, bootstrap and version control your \nconfiguration. All the data is pulled from native Craft fields, which makes for less \nmaintenance over time, _and keeps you in control of your data_. \n\nAdditionally, SEOMate adds a super-awesome SEO/social media preview to your Control Panel. The SEO preview taps into\nCraft's native Preview Targets, giving your clients a nice and familiar interface for previewing how their content will appear on Google, Facebook and Twitter.  \n\n  \n![Screenshot](resources/plugin_logo.png)\n\n## Requirements\n\nThis plugin requires Craft CMS 5.0.0 or later.  \n\n## Installation\n\nTo install the plugin, either install it from the plugin store, or follow these instructions:\n\n1. Install with composer via `composer require vaersaagod/seomate` from your project directory.\n2. Install the plugin in the Craft Control Panel under Settings → Plugins, or from the command line via `./craft install/plugin seomate`.\n3. For SEOMate to do anything, you need to [configure it](#configuring). But first, continue reading!\n\n---\n\n## SEOMate Overview\n\nSEOMate focuses on providing developers with the tools they need to craft their \nsite's SEO in three main areas; **meta data**, **sitemaps**, and **JSON-LD microdata**.\n\n### Meta data\nSEOMate doesn't provide any custom field types for entering meta data.\nInstead, you use native field types that come with Craft, and just tell SEOMate\nwhich fields to use.   \n\nYou do this by configuring _field profiles_ for the different field setups in your site. Sections and category groups \ncan be mapped to these profiles, or the desired profile can be set at the template level.  \n\nThe key config settings for meta data is `fieldProfiles`, `profileMap`, `defaultProfile`, \n`defaultMeta` and `additionalMeta`. Refer to the [\"Adding meta data\"](#adding-meta-data) \nsection on how to include the meta data in your page, and how to (optionally) override it at the template level.\n\n### Sitemaps\nSEOMate lets you create completely configuration based sitemaps for all your content.\nThe sitemaps are automatically updated with new elements, and will automatically be\nsplit into multiple sitemaps for scalability. \n\nTo enable sitemaps, set the `sitemapEnabled` config setting to `true` and configure the\ncontents of your sitemaps with `sitemapConfig`. Refer to the [\"Enabling sitemaps\"](#enabling-sitemaps)\nsection on how to enable and set up your sitemaps.\n\n### JSON-LD\nSEOMate provides a thin wrapper around the excellent [`spatie/schema-org`](https://github.com/spatie/schema-org) \npackage used for generating JSON-LD data structures. SEOMate exposes the `craft.schema`\ntemplate variable, that directly ties into the fluent [Schema API](https://github.com/spatie/schema-org/blob/master/src/Schema.php).\n\n_This method uses the exact same approach and signature as [Rias' Schema plugin](https://github.com/Rias500/craft-schema).\nIf you're only looking for a way to output JSON-LD, we suggest you use that plugin instead_.  \n\n### SEO preview  \nSEOMate provides a fancy \"SEO Preview\" preview target, for any and all elements with URLs, featuring \n_photo realistic approximations_ of how your content will appear in Google SERPs, or when shared on Facebook, \nTwitter/X and LinkedIn.  \n\n![img.png](resources/seo-preview.png)\n\n_If you don't like the SEO preview, or if you'd like it to only appear for entries in specific sections, check \nout the [previewEnabled](`#previewenabled-boolarray`) config setting._     \n\n### Things that SEOMate doesn't do...\nSo much! \n\n---\n\n## Adding meta data\n\nOut of the box, SEOMate doesn't add anything to your markup. To get started, add\n`{% hook 'seomateMeta' %}` to the `\u003chead\u003e` of your layout. Then, if you haven't already,\ncreate a config file named `seomate.php` in your `config` folder alongside your other \nCraft config files. This file can use [multi-environment configs](https://docs.craftcms.com/v3/config/environments.html#config-files), \nexactly the same as any other config file in Craft, but in the following examples we'll\nskip that part to keep things a bit more tidy. \n\nAll the config settings are documented in the [`Configuring`](#configuring) section, \nand there are quite a few! But to get you going, these are some fundamental concepts:  \n\n### Field profiles\n\nA _field profile_ in SEOMate is, essentially, a mapping of metadata attributes to the fields that SEOMate \nshould look at for those attributes' metadata values.    \n\nTo get started, create a profile called \"standard\" in `fieldProfiles`, and set that profile as the default \nfield profile using the `defaultProfile` setting:    \n\n```php\n\u003c?php\n\nreturn [\n    'defaultProfile' =\u003e 'standard',\n    \n    'fieldProfiles' =\u003e [\n        'standard' =\u003e [\n            'title' =\u003e ['seoTitle', 'heading', 'title'],\n            'description' =\u003e ['seoDescription', 'summary'],\n            'image' =\u003e ['seoImage', 'mainImage']\n        ]\n    ],\n];\n```\n\nThe above tells SEOMate to use the field profile `standard` to get element metadata from, as a default. \nSo, everytime a page template that has an element (i.e. `entry`, `category` or `product`) is loaded, SEOMate will \nstart by checking if that element has a field named `seoTitle`, and that this field has a value that can be used for \nthe title meta tag. If a field named `seoTitle` does not exist – or if it's empty – SEOMate continues to check if \nthere is a field named `heading`, and does the same thing. If `heading` is empty, it checks for `title`.  \nAnd so on, for every key in the field profile.  \n\n_💡 In addition to field handles, field profiles can also contain **functions** (i.e. closures), and/or  \n**Twig [object templates](https://craftcms.com/docs/5.x/system/object-templates.html)**. For documentation and examples for closures and object templates,  \nsee the [`fieldProfiles` setting](#fieldprofiles-array)!_  \n\n#### Mapping different field profiles to elements  \n\nNow, let's say we have a section with handle `news` that has a slightly different field setup than\nour other sections, so for entries in that section we want to pull data from some other fields. \nWe'll add another field profile to `fieldProfiles`, and make a mapping between the profile and the \nsection handle in `profileMap`:\n\n```php\n\u003c?php\n\nreturn [\n    'defaultProfile' =\u003e 'standard',\n    \n    'fieldProfiles' =\u003e [\n        'standard' =\u003e [\n            'title' =\u003e ['seoTitle', 'heading', 'title'],\n            'description' =\u003e ['seoDescription', 'summary'],\n            'image' =\u003e ['seoImage', 'mainImage']\n        ],\n        'newsprofile' =\u003e [\n            'title' =\u003e ['seoTitle', 'heading', 'title'],\n            'og:title' =\u003e ['ogSeo.title', 'ogTitle', 'heading', 'title'],\n            'description' =\u003e ['seoDescription', 'newsExcerpt', 'introText'],\n            'image' =\u003e ['seoImage', 'heroImage', 'newsBlocks.image:image']\n            'og:image' =\u003e ['ogSeo.image', 'ogImage', 'heroImage', 'newsBlocks.image:image']\n            'twitter:image' =\u003e ['twitterImage', 'heroImage', 'newsBlocks.image:image']\n        ]\n    ],\n    \n    'profileMap' =\u003e [\n        'news' =\u003e 'newsprofile',\n    ],    \n];\n```\n\nThe mapping between the \"news\" section and the profile is simple enough: the _key_ in `profileMap` can\nbe the handle for a section, entry type, category group, or Commerce product type, and the _value_ \nshould be the key for the profile in `fieldProfiles` that you want to use for matching elements.    \n\n_In this profile we also we have also used a couple of other SEOMate features._  \n\nFirst, notice that we have chosen to specify a field profile for `og:title`, `og:image`\nand `twitter:image` that we didn't have in the default profile. By default, the `autofillMap`\ndefines that if no value are set for `og:title` and `twitter:title`, we want to autofill those\nmeta tags with the value  from `title`. So in the `standard` profile, those values will be\nautofilled, while in the `newsprofile` we choose to customize some of them.\n\nSecondly, we're using a nested object syntax for `ogSeo.title` and `ogSeo.image` which could for\ninstance be used if you have a Content Block field (new in Craft 5.8) with values. Or any other \nfield type that returns a nested object. It goes as deep as you want, `someField.withAnObject.that.has.a.deep.structure`.\n\nThirdly, notice that we can specify to pull a value from a Matrix subfield by using the syntax\n`matrixFieldHandle.blockTypeHandle:subFieldHandle`.\n\n\n\n#### Profile map specificity   \n\n**In some cases there might be a need to create more specific field profile mappings.** For example, you might have\na section with the handle `news` _and_ a category group with the handle `news`, and you need their elements to use\ndifferent profiles. This can be achieved by using prefixes `section:` and/or `categoryGroup:`, e.g.   \n\n```php\n'profileMap' =\u003e [\n   'section:news' =\u003e 'newsprofile', // Will match entries in a section \"news\"\n   'categoryGroup:news' =\u003e 'newscategoryprofile', // Will match categories in a group \"news\"\n],\n```\n\nAnother use case for specific field profiles is if you need a certain entry type to use a specific profile, in which\ncase the `entryType:` prefix is the ticket:  \n\n```php\n'profileMap' =\u003e [\n   'section:news' =\u003e 'newsprofile', // Will match entries in a section \"news\"\n   'categoryGroup:news' =\u003e 'newscategoryprofile', // Will match categories in a group \"news\"\n   'pages' =\u003e 'pagesprofile',\n   'entryType:listPage' =\u003e 'listpageprofile', // Will match entries with an entry type \"listPage\"\n],\n```\n\nThe _specific_ field profiles (i.e. the ones using the `{sourceType}:` prefix) will take precedence over _unspecific_\nones. That means that – with the above config – entries in a section \"page\" will use the \"pagesprofile\" profile, \nunless they're using an entry type with the handle `listPage`, in which case the \"listpageprofile\" profile will be\nused. And, the \"listpageprofile\" will also be used for entries in _other_ sections, if they're using that same entry type.  \n\nThe following field profile specificity prefixes are supported:   \n\n* Entries: `section:{sectionHandle}` and `entryType:{entryTypeHandle}`  \n* Categories: `categoryGroup:{categoryGroupHandle}`  \n* Commerce products: `productType:{productTypeHandle}`  \n* Users: `user` \n\n### Default meta data\n\nField profiles are great for templates that have an element associated with them. But what about the ones\nthat don't? Or – what if there is no valid image in any of those image fields defined in the matching field profile?  \nThis is where `defaultMeta` comes into play. Let's say that we have a global set with handle `globalSeo`, with \nfields that we want to fall back on if everything else fails:  \n\n```php\n\u003c?php\n\nreturn [\n    'defaultMeta' =\u003e [\n        'title' =\u003e ['globalSeo.seoTitle'],\n        'description' =\u003e ['globalSeo.seoDescription'],\n        'image' =\u003e ['globalSeo.seoImages']\n    ],\n        \n    'defaultProfile' =\u003e 'standard',\n        \n    'fieldProfiles' =\u003e [\n        'standard' =\u003e [\n            'title' =\u003e ['seoTitle', 'heading', 'title'],\n            'description' =\u003e ['seoDescription', 'summary'],\n            'image' =\u003e ['seoImage', 'mainImage']\n        ],\n        'newsprofile' =\u003e [\n            'title' =\u003e ['seoTitle', 'heading', 'title'],\n            'og:title' =\u003e ['ogTitle', 'heading', 'title'],\n            'description' =\u003e ['seoDescription', 'newsExcerpt', 'introText'],\n            'image' =\u003e ['seoImage', 'heroImage', 'newsBlocks.image:image']\n            'og:image' =\u003e ['ogImage', 'heroImage', 'newsBlocks.image:image']\n            'twitter:image' =\u003e ['twitterImage', 'heroImage', 'newsBlocks.image:image']\n        ]\n    ],\n    \n    'profileMap' =\u003e [\n        'news' =\u003e 'newsprofile',\n    ],    \n];\n```\n \nThe `defaultMeta` setting works almost exactly the same as `fieldProfiles`, except that it\nlooks for objects and fields in you current Twig `context`, hence the use of globals.\n\n### Additional meta data\n\nLastly, we want to add some additional metadata like `og:type` and `twitter:card`, and for \nthat we have... `additionalMeta`:\n   \n```php\n\u003c?php\n\nreturn [\n    'defaultMeta' =\u003e [\n        'title' =\u003e ['globalSeo.seoTitle'],\n        'description' =\u003e ['globalSeo.seoDescription'],\n        'image' =\u003e ['globalSeo.seoImages']\n    ],\n        \n    'defaultProfile' =\u003e 'standard',\n        \n    'fieldProfiles' =\u003e [\n        'standard' =\u003e [\n            'title' =\u003e ['seoTitle', 'heading', 'title'],\n            'description' =\u003e ['seoDescription', 'summary'],\n            'image' =\u003e ['seoImage', 'mainImage']\n        ],\n        'newsprofile' =\u003e [\n            'title' =\u003e ['seoTitle', 'heading', 'title'],\n            'og:title' =\u003e ['ogTitle', 'heading', 'title'],\n            'description' =\u003e ['seoDescription', 'newsExcerpt', 'introText'],\n            'image' =\u003e ['seoImage', 'heroImage', 'newsBlocks.image:image']\n            'og:image' =\u003e ['ogImage', 'heroImage', 'newsBlocks.image:image']\n            'twitter:image' =\u003e ['twitterImage', 'heroImage', 'newsBlocks.image:image']\n        ]\n    ],\n    \n    'profileMap' =\u003e [\n        'news' =\u003e 'newsprofile',\n    ],\n    \n    'additionalMeta' =\u003e [\n        'og:type' =\u003e 'website',\n        'twitter:card' =\u003e 'summary_large_image',\n        \n        'fb:profile_id' =\u003e '{{ settings.facebookProfileId }}',\n        'twitter:site' =\u003e '@{{ settings.twitterHandle }}',\n        'twitter:author' =\u003e '@{{ settings.twitterHandle }}',\n        'twitter:creator' =\u003e '@{{ settings.twitterHandle }}',\n        \n        'og:see_also' =\u003e function ($context) {\n            $someLinks = [];\n            $matrixBlocks = $context['globalSeo']?-\u003esomeLinks?-\u003eall();\n            \n            if (!empty($matrixBlocks)) {\n                foreach ($matrixBlocks as $matrixBlock) {\n                    $someLinks[] = $matrixBlock-\u003esomeLinkUrl ?? '';\n                }\n            }\n            \n            return $someLinks;\n        },\n    ],\n];\n```\n\nThe `additionalMeta` setting takes either a string or an array, or a function that returns\neither of those, as the value for each property. Any Twig in the values are parsed, in the current \ncontext. \n\n\n### Customizing the meta output template\n\nSEOMate comes with a generic template that outputs the meta data it generates. You can override this \nwith your own template using the `metaTemplate` config setting.\n\n\n### Overriding meta data and settings from your templates\n\nYou can override the metadata and config settings directly from your templates by creating a\n`seomate` object and overriding accordingly:   \n\n```twig\n{% set seomate = {\n    profile: 'specialProfile',\n    element: craft.entries.section('newsListing').one(),\n    canonicalUrl: someOtherUrl,\n    \n    config: {\n        includeSitenameInTitle: false\n    },\n    \n    meta: {\n        title: 'Custom title',\n        'twitter:author': '@someauthor'     \n    },\n} %}\n```\n\nAll relevant config settings can be overridden inside the `config` key, and all metadata\ninside the `meta` key. You can also tell seomate to use a specific profile with the `profile` setting. \nAnd to use some other element as the base element to get metadata from, or provide one if the current \ntemplate doesn't have one, in the `element` key. And you can customize the canonicalUrl as needed. \nAnd... more.\n\n\n---\n\n## Enabling sitemaps\n\nTo enable sitemaps for your site, you need to set the `sitemapEnabled` config setting to `true`, \nand configure the contents of your sitemaps with `sitemapConfig`. In its simplest form, you can supply \nan array of section handles to the elements key, with the sitemap settings you want:\n\n```php\n'sitemapEnabled' =\u003e true,\n'sitemapLimit' =\u003e 100,\n'sitemapConfig' =\u003e [\n    'elements' =\u003e [\n        'news' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n        'projects' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 0.5],\n    ],\n],\n``` \n\nA sitemap index will be created at `sitemap.xml` at the root of your site, with links to \nsitemaps for each section, split into chunks based on `sitemapLimit`.\n\nYou can also do more complex element criterias, and manually add custom paths:\n\n```php\n'sitemapEnabled' =\u003e true,\n'sitemapLimit' =\u003e 100,\n'sitemapConfig' =\u003e [\n    'elements' =\u003e [\n        'news' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n        'projects' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 0.5],\n        'frontpages' =\u003e [\n            'elementType' =\u003e \\craft\\elements\\Entry::class,\n            'criteria' =\u003e ['section' =\u003e ['homepage', 'newsFrontpage', 'projectsFrontpage']],\n            'params' =\u003e ['changefreq' =\u003e 'daily', 'priority' =\u003e 1],\n        ],\n        'newscategories' =\u003e [\n            'elementType' =\u003e \\craft\\elements\\Category::class,\n            'criteria' =\u003e ['group' =\u003e 'newsCategories'],\n            'params' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 0.2],\n        ],\n        'semisecret' =\u003e [\n            'elementType' =\u003e \\craft\\elements\\Entry::class,\n            'criteria' =\u003e ['section' =\u003e 'semiSecret', 'notThatSecret' =\u003e true],\n            'params' =\u003e ['changefreq' =\u003e 'daily', 'priority' =\u003e 0.5],\n        ],\n    ],\n    'custom' =\u003e [\n        '/cookies' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n        '/terms-and-conditions' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n    ],\n],\n``` \n\nUsing the expanded criteria syntax, you can add whatever elements to your sitemaps.\n\n### Multi-site sitemaps  \n\nFor multi-site installs, SEOMate will automatically create sitemaps for each site. \nIf the [`outputAlternate`](#outputalternate-bool) config setting is enabled, sitemaps will include alternate URLs in \u003cxhtml:link\u003e entries.    \n\n---\n\n## Configuring\n\nSEOMate can be configured by creating a file named `seomate.php` in your Craft config folder, \nand overriding settings as needed. \n\n### cacheEnabled [bool]\n*Default: `'true'`*  \nEnables/disables caching of generated metadata. **The cached data will be automatically\ncleared when an element is saved**. To clear the metadata cache manually, Craft's \"Clear Caches\" CP utility can be used, or the core `clear-caches` CLI command.  \n\n### cacheDuration [int|string]\n*Default: `3600`*  \nDuration of meta cache in seconds. Can be set to an integer (seconds), or a valid PHP date interval string (e.g. 'PT1H').  \n\n### previewEnabled [bool|array]\n*Default: `true`*  \nEnable the \"SEO Preview\" preview target in the Control Panel everywhere (`true`), nowhere (`false`) or only for particular sections, category groups, entry types or Commerce product types (array of section and/or category group handles; e.g. `['news', 'events', 'homepage', 'section:blog', 'entryType:listPage']`, etc).  \n_Regardless of this config setting, the \"SEO Preview\" preview target is only ever added to sections and category groups with URLs._  \n\n### previewLabel [string|null]\n*Default: \"SEO Preview\"*  \nDefines the text label for the \"SEO Preview\" button and preview target inside the Control Panel.  \n\n### siteName [string|array|null]\n*Default: `null`*  \nDefines the site name to be used in metadata. Can be a plain string, or an array\nwith site handles as keys. Example:\n\n```php  \n'siteName' =\u003e 'My site'\n\n// or\n\n'siteName' =\u003e [\n    'default' =\u003e 'My site',\n    'other' =\u003e 'Another site',\n]\n```\n\nIf not set, SEOMate will try to get any site name defined in Craft's general config \nfor the current site. If that doesn't work, the current site's name will be used.   \n\n### metaTemplate [string]\n*Default: `''`*  \nSEOMate comes with a default meta template the outputs the configured meta tags. But,\nevery project is different, so if you want to customize the output you can use this \nsetting to provide a custom template (it needs to be in your site's template path). \n\n### includeSitenameInTitle [bool]\n*Default: `true`*  \nEnables/disabled if the site name should be displayed as part of the meta title.\n\n### sitenameTitleProperties [array]\n*Default: `['title']`*  \nDefines which meta title properties the site name should be added to. By default, \nthe site name is only added to the `title` meta tag.\n\nExample that also adds it to `og:title` and `twitter:title` tags:\n\n```php \n'sitenameTitleProperties' =\u003e ['title', 'og:title', 'twitter:title']\n```\n\n### sitenamePosition [string]\n*Default: `'after'`*  \nDefines if the site name should be placed `before` or `after` the rest of the\nmeta content.\n\n### sitenameSeparator [string]\n*Default: `'|'`*  \nThe separator between the meta tag content and the site name.\n\n### outputAlternate [bool|Closure]\n*Default: `true`*  \nEnables/disables output of alternate URLs in meta tags and sitemaps.  \n\nAlternate URLs are meant to provide search engines with alternate URLs  \n_for localized versions of the current page's content_.  \n\nIf you have a normal multi-locale website, you'll probably want to leave this setting\nenabled (i.e. set to `true`). However, if you're running a multi-site website where the  \nsites are distinct, you'll might want to set it to `false`, to prevent alternate URLs  \nfrom being output at all.    \n\nFor the Advanced Use Case (tm) – _e.g. multi-sites that have a mix of translated **and**  \ndistinct content_, it's also possible to break free from the shackles of the binary boolean,  \nand configure the `outputAlternate` setting with a closure function (that returns either `true`  \nor `false`).  \n\nThe `outputAlternate` closure will receive two parameters; `$element` (the current element) and  \n`$alternateElement` (the element from a different site, i.e. the *potential* alternate). This makes  \nit possible to compose custom logic, in order to determine if that alternate element's URL  \nshould be output or not.  \n\nAn example: the below closure would make SEOMate only output alternate URLs if the _language_ for  \nthe alternate element is different from the element's language:  \n\n```php\n'outputAlternate' =\u003e static fn($element, $alternateElement) =\u003e $element-\u003elanguage !== $alternateElement-\u003elanguage,\n```  \n\nIf this closure returns `true`, SEOMate will create an alternate URL for the `$alternateElement`.  \nIf it returns `false` (or any other falsey value), SEOMate will quietly pretend the `$alternateElement`  \ndoes not exist.  \n\n_For more information about alternate URLs, [refer to this article](https://support.google.com/webmasters/answer/189077)._   \n\n### alternateFallbackSiteHandle [string|null]\n*Default: `null`*  \nSets the site handle for the site that should be the fallback for unmatched languages, ie\nthe alternate URL with `hreflang=\"x-default\"`. \n\nUsually, this should be the globabl site that doesn't target a specific country. Or a site \nwith a holding page where the user can select language. For more information about alternate URLs,\n(refer to this article)[https://support.google.com/webmasters/answer/189077].   \n\n### altTextFieldHandle [string|null]\n*Default: `null`*  \nIf you have a field for alternate text on your assets, you should set this \nto your field's handle. This will pull and output the text for the `og:image:alt`\nand `twitter:image:alt` properties.\n\n### defaultProfile [string|null]\n*Default: `''`*  \nSets the default meta data profile to use (see the `fieldProfiles` config setting).\n\n### fieldProfiles [array]\n*Default: `[]`*  \nField profiles defines \"waterfalls\" for which fields should be used to fill which\nmeta tags. You can have as many or as few profiles as you want. You can define a default \nprofile using the `defaultProfile` setting, and you can map your sections and category \ngroups using the `profileMap` setting. You can also override which profile to use, directly \nfrom your templates.\n\nExample:\n\n```php\n'defaultProfile' =\u003e 'default',\n\n'fieldProfiles' =\u003e [\n    'default' =\u003e [\n        'title' =\u003e ['seoTitle', 'heading', 'title'],\n        'description' =\u003e ['seoDescription', 'summary'],\n        'image' =\u003e ['seoImage', 'mainImage']\n    ],\n    'products' =\u003e [\n        'title' =\u003e ['seoTitle', 'heading', 'title'],\n        'description' =\u003e ['seoDescription', 'productDescription', 'summary'],\n        'image' =\u003e ['seoImage', 'mainImage', 'heroMedia:media.image']\n    ],\n    'landingPages' =\u003e [\n        'title' =\u003e ['seoTitle', 'heading', 'title'],\n        'description' =\u003e ['seoDescription'],\n        'image' =\u003e ['seoImage', 'heroArea:video.image', 'heroArea:singleImage.image', 'heroArea:twoImages.images', 'heroArea:slideshow.images']\n    ],\n],\n```  \n\nField waterfalls are parsed from left to right. Empty or missing values are ignored, \nand SEOMate continues to look for a valid value in the next field.  \n\n#### Closures and object templates\n\nIn addition to field handle references, field profiles can also contain functions (i.e. _closures_) \nand/or Twig [object templates](https://craftcms.com/docs/5.x/system/object-templates.html).   \n\nField profile **closures** take a single argument `$element` (i.e. the element SEOMate is rendering meta data for).  \nHere's how a closure can look inside a field profile:  \n\n```php\n'fieldProfiles' =\u003e [\n    'default' =\u003e [\n        'title' =\u003e ['seoTitle', static function ($element) { return \"$element-\u003etitle - ($element-\u003eproductCode)\"; }],\n    ],\n]\n```\n\nGenerally, closures should return a string value (or `null`). The exception is image meta tags  \n(e.g. `'image'`, `'og:image'`, etc.), where SEOMate will expect an asset (or `null`) returned:    \n\n```php\n'fieldProfiles' =\u003e [\n    'default' =\u003e [\n        'image' =\u003e [static function ($element) { return $element-\u003eseoImage-\u003eone() ?? null; }],\n    ],\n]\n```\n\n**Object templates** are well documented in [the official Craft docs](https://craftcms.com/docs/5.x/system/object-templates.html).  \nHere's how they can be used in field profiles (the two examples are using short- and longhand syntaxes, respectively):     \n\n```php\n'fieldProfiles' =\u003e [\n    'default' =\u003e [\n        'title' =\u003e ['seoTitle', '{title} - ({productCode})', '{{ object.title }} - ({{ object.productCode }})'],\n    ],\n]\n```\n\nObject templates can only render strings, which make them less useful for image meta tags (that expect an asset returned).  \nBut if you really want to, you can render an asset ID, which SEOMate will use to query for the actual asset:\n\n```php\n'defaultMeta' =\u003e [\n    'default' =\u003e [\n        'image' =\u003e ['{seoImage.one().id}'],\n    ],\n]\n```\n\n### profileMap [array]\n*Default: `[]`*  \nThe profile map provides a way to map elements to different field profiles defined in `fieldProfiles`, via their \nsections, entry types, category groups and Commerce product types. **If no matching profile in this mapping is found, \nthe profile defined in `defaultProfile` will be used.**  \n\nThe keys in the `profileMap` should be a string containing one or several (comma-separated) element source handles,\nsuch as a section handle, entry type handle, category group handle or Commerce product type handle. These keys can \nbe specific, such as `section:news` (to explicitly match entries belonging to a \"news\" section) or unspecific, such \nas simply `news` (which would match elements belong to _either_ a section, entry type, category group or product type \nwith the handle `'news'`).  \n\nKeys in `profileMap` are matched to elements from _most_ to _least_ specific, e.g. for an element with an \nentry type `listPage`, if the `profileMap` contained both a `listPage` and an `entryType:listPage` key, \nthe latter would be used for that element.  \n\nThe following field profile specificity prefixes are supported:\n\n* Entries: `section:{sectionHandle}` and `entryType:{entryTypeHandle}`\n* Categories: `categoryGroup:{categoryGroupHandle}`\n* Commerce products: `productType:{productTypeHandle}`\n* Users: `user`\n\nExample:  \n\n```php\n'profileMap' =\u003e [\n    'news' =\u003e 'newsProfile',\n    'section:products' =\u003e 'productsProfile',\n    'section:frontpage,section:campaigns' =\u003e 'landingPagesProfile',\n    'entryType:listPage' =\u003e 'listPageProfile',\n    'categoryGroup:newsCategories' =\u003e 'newsCategoriesProfile',\n],\n```\n\n### defaultMeta [array]\n*Default: `[]`*  \nThis setting defines the default meta data that will be used if no valid meta data\nwas found for the current element (ie, none of the fields provided in the field profile\nexisted, or they all had empty values). \n\nThe waterfall looks for meta data in the global _Twig context_. In the example\nbelow, we're falling back to using fields in two global sets, with handles `globalSeo` \nand `settings` respectively:\n\n```php\n'defaultMeta' =\u003e [\n    'title' =\u003e ['globalSeo.seoTitle'],\n    'description' =\u003e ['globalSeo.seoDescription', 'settings.companyInfo'],\n    'image' =\u003e ['globalSeo.seoImages']\n],\n```\n\n#### Closures and object templates\n\nIn addition to field handle references, `defaultMeta` can also contain functions (i.e. _closures_)\nand/or Twig [object templates](https://craftcms.com/docs/5.x/system/object-templates.html).  \n\nField profile **closures** take a single argument `$context` (i.e. an array; the global Twig context).    \nHere's how a closure can look inside `defaultMeta`:\n\n```php\n'defaultMeta' =\u003e [\n    'title' =\u003e [static function ($context) { return $context['siteName'] . ' is awesome!'; }],\n]\n```  \n\nGenerally, closures should return a string value (or `null`). The exception is image meta tags  \n(e.g. `'image'`, `'og:image'`, etc.), where SEOMate will expect an asset (or `null`) returned:  \n\n```php\n'defaultMeta' =\u003e [\n    'image' =\u003e [static function ($context) { return $context['defaultSeoImage']-\u003eone() ?? null; }],\n]\n```\n\n**Object templates** are well documented in [the official Craft docs](https://craftcms.com/docs/5.x/system/object-templates.html).  \nHere's how they can be used in `defaultMeta` (note that for `defaultMeta`, the `object` variable refers to the global  \nTwig context):  \n\n```php\n'defaultMeta' =\u003e [\n    'title' =\u003e ['{siteName} is awesome!', '{{ object.siteName }} is awesome!'],\n]\n```\n\nObject templates can only render strings, which make them less useful for image meta tags (that expect an asset returned).  \nBut if you really want to, you can render an asset ID, which SEOMate will use to query for the actual asset:  \n\n```php\n'defaultMeta' =\u003e [\n    'image' =\u003e ['{defaultSeoImage.one().id}'],\n]\n```  \n\n### additionalMeta [array]\n*Default: `[]`*  \n\nThe additional meta setting defines all other meta data that you want SEOMate\nto output. This is a convenient way to add more global meta data, that is used\nthroughout the site. Please note that you don't have to use this, you could also\njust add the meta data directly to your meta, or html head, template.\n\nThe key defines the meta data property to output, and the value could be either\na plain text, some twig that will be parsed based on the current context, an array\nwhich will result in multiple tags of this property being output, or a function.\n\nIn the example below, some properties are plain text (`og:type` and `twitter:card`),\nsome contains twig (for instance `fb:profile_id`), and for `og:see_also` we provide\na function that returns an array. \n\n```php\n'additionalMeta' =\u003e [\n    'og:type' =\u003e 'website',\n    'twitter:card' =\u003e 'summary_large_image',\n    \n    'fb:profile_id' =\u003e '{{ settings.facebookProfileId }}',\n    'twitter:site' =\u003e '@{{ settings.twitterHandle }}',\n    'twitter:author' =\u003e '@{{ settings.twitterHandle }}',\n    'twitter:creator' =\u003e '@{{ settings.twitterHandle }}',\n    \n    'og:see_also' =\u003e function ($context) {\n        $someLinks = [];\n        $matrixBlocks = $context['globalSeo']-\u003esomeLinks-\u003eall() ?? null;\n        \n        if ($matrixBlocks \u0026\u0026 count($matrixBlocks) \u003e 0) {\n            foreach ($matrixBlocks as $matrixBlock) {\n                $someLinks[] = $matrixBlock-\u003esomeLinkUrl ?? '';\n            }\n        }\n        \n        return $someLinks;\n    },\n],\n```\n\n### metaPropertyTypes [array]\n*Default: (see below)*  \nThis setting defines the type and limitations of the different meta tags. Currently,\nthere are two valid types, `text` and `image`. \n\nExample/default value:\n```php\n[\n    'title,og:title,twitter:title' =\u003e [\n        'type' =\u003e 'text',\n        'minLength' =\u003e 10,\n        'maxLength' =\u003e 60\n    ],\n    'description,og:description,twitter:description' =\u003e [\n        'type' =\u003e 'text',\n        'minLength' =\u003e 50,\n        'maxLength' =\u003e 300\n    ],\n    'image,og:image,twitter:image' =\u003e [\n        'type' =\u003e 'image'\n    ],\n]\n```\n\n### applyRestrictions [bool]\n*Default: `false`*  \nEnables/disables enforcing of restrictions defined in `metaPropertyTypes`.\n\n### validImageExtensions [array]\n*Default: `['jpg', 'jpeg', 'gif', 'png']`*  \nValid filename extensions for image property types. \n\n### truncateSuffix [string]\n*Default: `'…'`*  \nSuffix to add to truncated meta values.\n\n### returnImageAsset [bool]\n*Default: `false`*  \nBy default, assets will be transformed by SEOMate, and the resulting URL is\ncached and passed to the template. \n\nBy enabling this setting, the asset itself will instead be returned to the \ntemplate. This can be useful if you want to perform more complex transforms,\nor output more meta tags where you need more asset data, that can only be done\nat the template level. Please note that you'll probably want to provide a custom \n`metaTemplate`, and that caching will not work (you should instead use your own \ntemplate caching).  \n\n### useImagerIfInstalled [bool]\n*Default: `true`*  \nIf [Imager](https://github.com/aelvan/Imager-Craft) is installed, SEOMate will \nautomatically use it for transforms (they're mates!), but you can disable this \nsetting to use native Craft transforms instead. \n\n### imageTransformMap [array]\n*Default: (see below)*  \nDefines the image transforms that are to be used for the different meta image\nproperties. All possible options of Imager or native Craft transforms can be used. \n\nDefault value:\n```php\n[\n    'image' =\u003e [\n        'width' =\u003e 1200,\n        'height' =\u003e 675,\n        'format' =\u003e 'jpg',\n    ],\n    'og:image' =\u003e [\n        'width' =\u003e 1200,\n        'height' =\u003e 630,\n        'format' =\u003e 'jpg',\n    ],\n    'twitter:image' =\u003e [\n        'width' =\u003e 1200,\n        'height' =\u003e 600,\n        'format' =\u003e 'jpg',\n    ],\n]\n```\n\nExample where the Facebook and Twitter images has been sharpened, desaturated\nand given a stylish blue tint (requires Imager):\n\n```php \n'imageTransformMap' =\u003e [\n    'image' =\u003e [\n        'width' =\u003e 1200,\n        'height' =\u003e 675,\n        'format' =\u003e 'jpg'\n    ],\n    'og:image' =\u003e [\n        'width' =\u003e 1200,\n        'height' =\u003e 630,\n        'format' =\u003e 'jpg',\n        'effects' =\u003e [\n            'sharpen' =\u003e true,\n            'modulate' =\u003e [100, 0, 100], \n            'colorBlend' =\u003e ['rgb(0, 0, 255)', 0.5]\n        ]\n    ],\n    'twitter:image' =\u003e [\n        'width' =\u003e 1200,\n        'height' =\u003e 600,\n        'format' =\u003e 'jpg',\n        'effects' =\u003e [\n            'sharpen' =\u003e true,\n            'modulate' =\u003e [100, 0, 100], \n            'colorBlend' =\u003e ['rgb(0, 0, 255)', 0.5]\n        ]\n    ],\n],\n```\n\n### autofillMap [array]\n*Default: (see below)*  \nMap of properties that should be automatically filled by another property,\n_if they're empty after the profile has been parsed_. \n\nDefault value:\n```php\n[\n    'og:title' =\u003e 'title',\n    'og:description' =\u003e 'description',\n    'og:image' =\u003e 'image',\n    'twitter:title' =\u003e 'title',\n    'twitter:description' =\u003e 'description',\n    'twitter:image' =\u003e 'image',\n]\n```\n\n### tagTemplateMap [array]\n*Default: (see below)*  \nMap of output templates for the meta properties. \n\nExample/default value:\n```php\n[\n    'default' =\u003e '\u003cmeta name=\"{{ key }}\" content=\"{{ value }}\"\u003e',\n    'title' =\u003e '\u003ctitle\u003e{{ value }}\u003c/title\u003e',\n    '/^og:/,/^fb:/' =\u003e '\u003cmeta property=\"{{ key }}\" content=\"{{ value }}\"\u003e',\n]\n```\n\n### sitemapEnabled [bool]\n*Default: `false`*  \nEnables/disables sitemaps.\n\n### sitemapName [string]\n*Default: `'sitemap'`*  \nName of sitemap. By default it will be called `sitemap.xml`.\n\n### sitemapLimit [int]\n*Default: `500`*  \nNumber of URLs per sitemap. SEOMate will automatically make a sitemap index\nand split up your sitemap into chunks with a maximum number of URLs as per\nthis setting. A lower number could ease the load on your server when the \nsitemap is being generated.\n\n### sitemapConfig [array]\n*Default: `[]`*  \nDefines the content of the sitemaps. The configuration consists of two main \nkeys, `elements` and `custom`. In `elements`, you can define sitemaps that \nwill automatically query for elements in certain sections or based on custom \ncriterias. \n\nIn `custom` you add paths that are added to a separate custom sitemap, and you \nmay also add links to manually generated sitemaps in `additionalSitemaps`. Both \nof these settings can be a flat array of custom urls or sitemap paths that you \nwant to add, or a nested array where the keys are site handles, to specify \ncustom urls/sitemaps that are site specific, or `'*'`, for additional ones. \nSee the example below. \n\nIn the example below, we get all elements from the sections with handles \n`projects` and `news`, query for entries in four specific \nsections and all categories in group `newsCategories`. In addition to these, \nwe add two custom urls, and two additional sitemaps.\n\n```php\n'sitemapConfig' =\u003e [\n    'elements' =\u003e [\n        'projects' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 0.5],\n        'news' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 0.5],\n        \n        'indexpages' =\u003e [\n            'elementType' =\u003e \\craft\\elements\\Entry::class,\n            'criteria' =\u003e ['section' =\u003e ['frontpage', 'newsListPage', 'membersListPage', 'aboutPage']],\n            'params' =\u003e ['changefreq' =\u003e 'daily', 'priority' =\u003e 0.5],\n        ],\n        'newscategories' =\u003e [\n            'elementType' =\u003e \\craft\\elements\\Category::class,\n            'criteria' =\u003e ['group' =\u003e 'newsCategories'],\n            'params' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 0.2],\n        ],\n    ],\n    'custom' =\u003e [\n        '/custom-1' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n        '/custom-2' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n    ],\n    'additionalSitemaps' =\u003e [\n        '/sitemap-from-other-plugin.xml',\n        '/manually-generated-sitemap.xml'\n    ]\n],\n```\n\nExample with site specific custom urls and additional sitemaps:\n\n```php\n'sitemapConfig' =\u003e [\n    /* ... */ \n    \n    'custom' =\u003e [\n        '*' =\u003e [\n            '/custom-global-1' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n            '/custom-global-2' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n        ],\n        'english' =\u003e [\n            '/custom-english' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n        ],\n        'norwegian' =\u003e [\n            '/custom-norwegian' =\u003e ['changefreq' =\u003e 'weekly', 'priority' =\u003e 1],\n        ]\n    ],\n    'additionalSitemaps' =\u003e [\n        '*' =\u003e [\n            '/sitemap-from-other-plugin.xml',\n            '/sitemap-from-another-plugin.xml',\n        ],\n        'english' =\u003e [\n            '/manually-generated-english-sitemap.xml',\n        ],\n        'norwegian' =\u003e [\n            '/manually-generated-norwegian-sitemap.xml',\n        ]\n    ]\n],\n``` \n\n**Using the expanded criteria syntax, you can query for whichever type of element, \nas long as they are registered as a valid element type in Craft.**\n\nThe main sitemap index will be available on the root of your site, and named\naccording to the `sitemapName` config setting (`sitemap.xml` by default). The actual\nsitemaps will be named using the pattern `sitemap_\u003celementKey\u003e_\u003cpage\u003e.xml` for \nelements and `sitemap_custom.xml` for the custom urls.\n\n### sitemapSubmitUrlPatterns [array]\n*Default: (see below)*\nURL patterns that your sitemaps are submitted to. \n\nExample/default value:\n```php\n'sitemapSubmitUrlPatterns' =\u003e [\n    'http://www.google.com/webmasters/sitemaps/ping?sitemap=',\n    'http://www.bing.com/webmaster/ping.aspx?siteMap=',\n];\n```\n\n\n---\n\n## Template variables\n\n### craft.seomate.getMeta([config=[]])\nReturns an object with the same meta data that is passed to the meta data \ntemplate. \n\n```twig\n{% set metaData = craft.seomate.getMeta() %}\nMeta Title: {{ metaData.meta.title }} \nCanonical URL: {{ metaData.canonicalUrl }} \n```\n\nYou can optionally pass in a config object the same way you would in your template \noverrides, to customize the data, or use a custom element as the source:\n\n```twig\n{% set metaData = craft.seomate.getMeta({\n    profile: 'specialProfile',\n    element: craft.entries.section('newsListing').one(),\n    canonicalUrl: someOtherUrl,\n    \n    config: {\n        includeSitenameInTitle: false\n    },\n    \n    meta: {\n        title: 'Custom title',\n        'twitter:author': '@someauthor'     \n    },\n}) %}\n```\n\n### craft.schema\nYou can access all the different schemas in the [`spatie/schema-org`](https://github.com/spatie/schema-org) \npackage through this variable endpoint. If you're using PHPStorm and the Symfony plugin, \nyou can get full autocompletion by assigning type hinting (see example below)\n\nExample:\n\n```twig   \n{# @var schema \\Spatie\\SchemaOrg\\Schema #}\n{% set schema = craft.schema %}\n\n{{ schema.recipe\n    .dateCreated(entry.dateCreated)\n    .dateModified(entry.dateUpdated)\n    .datePublished(entry.postDate)\n    .copyrightYear(entry.postDate | date('Y'))\n    .name(entry.title)\n    .headline(entry.title)\n    .description(entry.summary | striptags)\n    .url(entry.url)\n    .mainEntityOfPage(entry.url)\n    .inLanguage('nb_no')\n    .author(schema.organization\n        .name('The Happy Chef')\n        .url('https://www.thehappychef.xyz/')\n    )\n    .recipeCategory(categories)\n    .recipeCuisine(entry.cuisine)\n    .keywords(ingredientCategories | merge(categories) | join(', '))\n    .recipeIngredient(ingredients)\n    .recipeInstructions(steps)\n    .recipeYield(entry.portions ~ ' porsjoner')\n    .cookTime('PT'~entry.cookTime~'M')\n    .prepTime('PT'~entry.prepTime~'M')\n    .image(schema.imageObject\n        .url(image.url)\n        .width(schema.QuantitativeValue.value(image.getWidth()))\n        .height(schema.QuantitativeValue.value(image.getHeight()))\n    )\n| raw }}\n```\n\n_Again, if you're only looking for a way to output JSON-LD, we suggest you \nuse [Rias' Schema plugin](https://github.com/Rias500/craft-schema) instead_.\n\n### craft.seomate.renderMetaTag(key, value)\nRenders a meta tag based on `key` and `value`. Uses the `tagTemplateMap` config\nsetting to determine how the markup should look. \n\nDoes exactly the same thing as the `renderMetaTag` twig function.\n\n### craft.seomate.breadcrumbSchema(breadcrumb)\nA convenient method for outputting a JSON-LD breadcrumb. The method takes an\narray of objects with properties for `url` and `name`, and outputs a valid \nSchema.org JSON-LD data structure.\n\nExample:\n```twig\n{% set breadcrumb = [\n    {\n        'url': siteUrl,\n        'name': 'Frontpage'\n    },\n    {\n        'url': currentCategory.url,\n        'name': currentCategory.title\n    },\n    {\n        'url': entry.url,\n        'name': entry.title\n    }\n] %}\n\n{{ craft.seomate.breadcrumbSchema(breadcrumb) }}\n```\n\n---\n\n## Twig functions\n\n### renderMetaTag(key, value)\nRenders a meta tag based on `key` and `value`. Uses the `tagTemplateMap` config\nsetting to determine how the markup should look.\n\nDoes exactly the same thing as the `craft.seomate.renderMetaTag` template variable.\n\n\n---\n\n## Price, license and support\n\nThe plugin is released under the MIT license, meaning you can do what ever you want with it as long \nas you don't blame us. **It's free**, which means there is absolutely no support included, but you \nmight get it anyway. Just post an issue here on github if you have one, and we'll see what we can do. \n\n## Changelog\n\nSee [CHANGELOG.MD](https://raw.githubusercontent.com/vaersaagod/seomate/master/CHANGELOG.md).\n\n## Credits\n\nBrought to you by [Værsågod](https://www.vaersaagod.no)\n\nIcon designed by [Freepik from Flaticon](https://www.flaticon.com/authors/freepik).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaersaagod%2Fseomate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvaersaagod%2Fseomate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaersaagod%2Fseomate/lists"}