For the complete documentation index, see llms.txt. This page is also available as Markdown.

Upgrade 2.0 to 3.0

Upgrade from Advanced SEO 2.0 to 3.0. Most breaking changes are handled by automated upgrade scripts.

Advanced SEO 3.0 introduces a significant internal refactor that improves the architecture, maintainability, and user experience of the addon. Most breaking changes have automated upgrade scripts, so the upgrade should be seamless for most users. First read through this guide to see if there's anything you need to adjust. Most items only apply if you've customized blueprints, published views, or written custom code against the GraphQL or sitemap APIs.

Upgrade using Composer

In your composer.json, change the requirement from:

- "aerni/advanced-seo": "^2.0"
+ "aerni/advanced-seo": "^3.0"

Then run:

composer update aerni/advanced-seo --with-dependencies

Automated upgrade scripts should run right after installation. If they don't trigger, see Troubleshooting.

Upgrade Summary

The following changes require manual action. All other changes are handled automatically.

Change
Impact
Action

High

Require package manually

High

Remove custom fields

Medium

Update queries

Medium

Update event listeners

Low

Update published views

Low

Update published views

Low

Remove from published config

Low

Remove custom templates

Low

Update custom templates

Low

Delete orphaned images

Low

Set card size in site defaults

Low

Review sitemap settings

High Impact Changes

Requirements

  • PHP 8.4+

  • Laravel 12+

  • Statamic 6+

Screenshot Package

Affects users of the social images generator.

The social images generator now uses spatie/laravel-screenshot and is no longer bundled as a dependency. This package supports Browsershot and Cloudflare Browser Rendering as screenshot drivers.

To restore existing functionality, require both the screenshot package and Browsershot:

Alternatively, you can use Cloudflare Browser Rendering instead of Browsershot. Refer to the installation guide for details. To customize screenshot settings, publish the config:

Blueprint Customization Removed

Affects users who customized Advanced SEO fieldsets or used the advanced_seo fieldtype in their blueprints.

Support for blueprint customization has been removed. This includes:

  • The Advanced SEO fieldsets (e.g. Advanced SEO (Main), Title & Description, Open Graph, etc.) that could be edited to customize which fields appear in the SEO tab

  • The Advanced SEO fieldtype (advanced_seo) that allowed placing individual SEO fields anywhere in a blueprint

Remove any advanced_seo fieldtype fields from your blueprints and delete any customized Advanced SEO fieldsets. The SEO tab fields are now managed entirely by the addon and cannot be customized.

Medium Impact Changes

GraphQL

Affects users of the GraphQL API. All GraphQL changes require updating your queries.

The GraphQL API has been significantly reworked in 3.0. If you'd rather rewrite your queries from scratch, see the GraphQL reference for the current API.

Renamed Query and Types

The seoDefaults query has been renamed to seoSet:

All type names have been updated to use "Set" instead of "Defaults":

Old Type Name
New Type Name

siteDefaults

siteSet

contentDefaults

collectionSet / taxonomySet

Flattened Site Set Structure

The siteDefaults type previously contained nested sub-types. These have been consolidated into a single flat siteSet type:

Removed sub-types
Removed Type
Replacement

generalDefaults

Fields moved directly onto siteSet

indexingDefaults

Fields moved directly onto siteSet

socialMediaDefaults

Fields moved directly onto siteSet

analyticsDefaults

Fields moved directly onto siteSet

faviconsDefaults

Fields moved directly onto siteSet

Removed seoSet Fields

The following fields have been removed from the siteSet type as they are now configured per collection/taxonomy:

  • excluded_collections

  • excluded_taxonomies

  • social_images_generator_collections

Disabled Features

Fields belonging to disabled features are now completely removed from the schema. Previously, disabled feature fields were still present but returned null. Now, if a feature is disabled in config/advanced-seo.php, its fields will not appear in the schema at all.

Removed baseUrl Argument

The baseUrl argument has been removed from the seoMeta query. To rewrite absolute URLs for headless setups, configure your frontend domain in Statamic's sites configuration (resources/sites.yaml) instead.

computed Field Changes

Change
Field
Notes

Added

twitter_card

Returns the card size (summary or summary_large_image)

Removed

title

Use raw data title field

Removed

og_title

Use raw data og_title field

Removed

twitter_title

Use raw data og_title field

Removed

twitter_image

Use raw data og_image field

Removed

og_image

Use raw data og_image field

Removed

generated_og_image

Use raw data og_image field

siteSet Field Changes

Change
Field
Notes

Added

twitter_card

Returns the card size (summary or summary_large_image)

Renamed

title_separator → separator

Renamed

cloudflare_web_analytics → cloudflare_beacon_token

More descriptive name

Renamed

google_tag_manager → gtm_container_id

More descriptive name

Removed

nofollow

Now per-collection/entry only

Removed

use_fathom

Check fathom_id presence instead

Removed

use_cloudflare_web_analytics

Check cloudflare_beacon_token presence instead

Removed

use_google_tag_manager

Check gtm_container_id presence instead

Removed

twitter_summary_image

Use og_image

Removed

twitter_summary_large_image

Use og_image

seoMeta Raw Type Field Changes

Change
Field
Notes

Removed

site_name_position

Composed into title

Removed

twitter_card

Use seoSet { site { twitter_card } } or seoMeta { computed { twitter_card } }

Removed

twitter_title

Use og_title

Removed

twitter_description

Use og_description

Removed

twitter_summary_image

Use og_image

Removed

twitter_summary_large_image

Use og_image

Removed

sitemap_priority

Google and Bing ignore this value

Removed

sitemap_change_frequency

Google and Bing ignore this value

collectionSet and taxonomySet Field Changes

Change
Field
Notes

Removed

site_name_position

Composed into title

Removed

twitter_card

Use seoSet { site { twitter_card } } or seoMeta { computed { twitter_card } }

Removed

twitter_title

Use og_title

Removed

twitter_description

Use og_description

Removed

twitter_summary_image

Use og_image

Removed

twitter_summary_large_image

Use og_image

Removed

sitemap_priority

Google and Bing ignore this value

Removed

sitemap_change_frequency

Google and Bing ignore this value

Removed

canonical_type

Per-entry/term only (still on seoMeta)

Removed

canonical_entry

Per-entry/term only (still on seoMeta)

Removed

canonical_custom

Per-entry/term only (still on seoMeta)

seoSitemaps Query

The seoSitemaps query has been completely restructured for a simpler, flatter API:

Key changes:

  • site is now a required query argument (was optional on nested fields)

  • type argument (collection, taxonomy, custom) replaces the nested fields

  • baseUrl has been removed. Configure your frontend domain in resources/sites.yaml instead.

  • Returns a list of sitemaps with id, type, handle, lastmod, and nested urls array

Custom Sitemap Registration

Affects users who registered custom sitemaps.

The custom sitemaps API has been reworked. Closure-based registration via Sitemap::register() is no longer supported. Custom sitemaps now explicitly declare their site using the $site property, and the sitemap index automatically includes them. The site defaults to the default Statamic site if not set.

Inline Sitemaps

Drop the Sitemap::register() closure wrapper and call register() directly on the sitemap:

Class-Based Sitemaps

Class-based sitemaps now extend CustomSitemap instead of BaseSitemap. Define the $handle and $site as properties and use $this->makeUrl() instead of the facade:

You can register class-based sitemaps in a service provider or via the config:

See Custom Sitemaps for the full API reference.

Events

Affects users listening for SeoDefaultSetSaved.

The SeoDefaultSetSaved event has been renamed to SeoSetLocalizationSaved. The public property has been renamed from $defaults to $localization.

New events have been added:

  • SeoSetConfigSaved — Fired when a set's configuration is saved

  • SeoSetConfigDeleted — Fired when a set's configuration is deleted

  • SeoSetLocalizationDeleted — Fired when a localization is deleted

Low Impact Changes

Custom Views

Affects users who published or customized the _twitter.antlers.html or _analytics.antlers.html snippets.

Update the following references:

Old Variable
New Variable

seo:twitter_title

seo:og_title

seo:twitter_description

seo:og_description

seo:twitter_image

seo:og_image

seo:twitter_image:alt

seo:og_image:alt

seo:cloudflare_web_analytics

seo:cloudflare_beacon_token

seo:google_tag_manager

seo:gtm_container_id

Unified Social Image Field

Affects users who published or customized views referencing seo:generated_og_image.

The seo_generated_og_image field has been removed. The seo_og_image field now handles both generated and user-defined images automatically based on the seo_generate_social_images toggle state.

When the toggle is enabled, seo_og_image returns the generated image. When disabled, it returns the user-defined image.

Update any views that reference seo:generated_og_image to use seo:og_image.

Generator Config Changes

Affects users who published config/advanced-seo.php with the generate_on_save option.

The generate_on_save option has been removed from the generator config:

Remove this option from your published config file if present.

Social image generation now works as follows:

  • After saving — Images are generated using Laravel's defer(), which runs after the response is sent (sync driver) or dispatches a queued job. Content hashing ensures images are only regenerated when content actually changes.

  • On demand — If a generated image is missing, it will be regenerated on-the-fly on the next frontend request.

Removed Twitter Image Generation

Affects users with custom social images generator themes.

The social images generator no longer generates separate Twitter images. Only the Open Graph image is generated. The twitter_summary and twitter_summary_large_image config presets are still used to resize the shared image for the Twitter meta tags via Glide, but no separate images are generated.

Remove the twitter_summary.antlers.html and twitter_summary_large_image.antlers.html templates from your custom themes. Only open_graph.antlers.html is used.

Template Changes

Affects users whose social image templates reference the $group variable.

The $group variable has been removed from the data passed to social images generator templates. If your templates reference this variable, update them.

Image Storage Directory

Affects users of the social images generator.

Generated social images are now stored in social_images/collection-{handle}/ and social_images/taxonomy-{handle}/ subdirectories instead of social_images/{handle}/. This adds support for taxonomy terms and avoids collisions between collections and taxonomies with the same handle.

Existing images in the old directory structure will not be migrated automatically. They will be regenerated in the new location on the next save or frontend request. You may delete the orphaned images in the old directories.

Twitter Card Setting

Affects users who previously set the X (Twitter) card size to summary (Small) on any entry, term, or collection/taxonomy default.

The X (Twitter) card size is no longer configurable per entry, term, or collection/taxonomy. It has been moved to the site defaults and applies globally. The default card size is summary_large_image (Large). If you previously used summary (Small), set your preferred card size in the site defaults after upgrading.

Automated Changes

Everything in this section is handled by upgrade scripts. No action required. These changes are documented for reference.

Pro Edition

Existing users are automatically upgraded to the Pro edition by adding 'aerni/advanced-seo' => 'pro' to config/statamic/editions.php. This preserves full feature access since Advanced SEO 2.0 didn't have a free edition.

Permissions

The permission system has been simplified. Old granular permissions have been replaced with three new permissions:

  • configure seo — Full access to all SEO settings, defaults, and content editing

  • edit seo defaults — Edit collection and taxonomy defaults

  • edit seo content — Access the SEO tab on entries and terms

All existing roles receive the edit seo content permission to maintain backward compatibility.

Advanced SEO permissions now layer on top of Statamic's native collection and taxonomy permissions:

  • To edit SEO defaults for a collection or taxonomy, a user needs edit seo defaults (or configure seo) and either Statamic's configure collections / configure taxonomies or edit {handle} entries / edit {handle} terms permission.

  • To configure SEO settings for a collection or taxonomy, a user needs configure seo and Statamic's configure collections / configure taxonomies permission.

We recommend reviewing your roles after upgrading to confirm users have the right combination of Advanced SEO and Statamic permissions.

Single-Site Data Structure

Single-site installations now use the same data structure as multi-site, with site-scoped localization files:

Site SEO Sets

The five separate site SEO sets (site::general, site::indexing, site::social_media, site::analytics, site::favicons) have been consolidated into a single site::defaults set, with tabs providing the UI grouping. For file-based installations, the file structure has changed accordingly:

Disabled Collections and Taxonomies

The disabled configuration option has been removed from config/advanced-seo.php. Collections and taxonomies are now disabled individually through the Control Panel via the "Configure" button on each set.

Localization Origin Field

The origin field has been removed from localizations. Origin configuration is now stored centrally in the set config using an origins array.

Eloquent Driver

The advanced_seo_defaults table has been replaced by seo_set_localizations. A new seo_set_configs table stores configuration data (enabled state, origins, etc.). New migrations are published and run automatically, and the old table is dropped after data is migrated.

SEO Field Values

Simplified Field UI

The SEO source fields have been simplified from a three-state toggle (Auto/Default/Custom) to a two-state inheritance model. Fields are now either inherited (showing the default value) or custom (user-set value). The toggle has been removed. Transitioning between states now happens implicitly through editing and a Reset action.

Field Handle Syntax Replaced

The @field:handle syntax for referencing other fields has been replaced with standard Antlers {{ handle }} syntax. You can now use the full power of Antlers in your SEO fields, including modifiers like {{ content | truncate(90, '...') }}. The @auto and @null sentinel values are also migrated.

Site Name Position Composed into Title

The seo_site_name_position field has been removed. Its value is composed directly into the seo_title field using Antlers syntax, giving you full control over the title format:

Position

Resulting seo_title

start

{{ site_name }} {{ separator }} {{ title }}

end

{{ title }} {{ separator }} {{ site_name }}

disabled

{{ title }}

Title Separator Renamed

The title_separator field in site defaults has been renamed to separator.

X (Twitter) Social Sharing

The X (Twitter) social sharing has been significantly simplified. Instead of maintaining separate Twitter-specific fields, the addon now uses a unified social image shared between Open Graph and Twitter. The card size is now a site-level default.

Removed Fields

The following fields have been removed from entries, terms, and SEO set localizations:

Removed Field
Replacement

seo_twitter_card

seo_twitter_title

Uses seo_og_title

seo_twitter_description

Uses seo_og_description

seo_twitter_summary_image

Uses seo_og_image

seo_twitter_summary_large_image

Uses seo_og_image

The following fields have been removed from the site-wide social media defaults:

Removed Field
Replacement

twitter_summary_image

Uses og_image

twitter_summary_large_image

Uses og_image

Nofollow Removed from Site Defaults

The site-wide nofollow toggle has been removed from the site defaults. It has no practical use case (if you need to prevent crawling entirely, the crawling.environments configuration already forces both noindex and nofollow when the environment is not listed). Nofollow is now managed per collection/taxonomy in the content defaults and per entry/term.

Social Images Generator

Per-Collection Settings

The social_images_generator_collections field has been removed from the site defaults. The social images generator is now enabled per-collection using the social_images_generator toggle in the collection config.

Removed Social Image Preview Targets

The social images generator no longer registers live preview targets for entries. Social image previews are now shown directly in the publish form via a new inline preview fieldtype with real-time theme switching.

Canonical URL

Removed from Collection/Taxonomy Defaults

The canonical URL fields (seo_canonical_type, seo_canonical_entry, seo_canonical_custom) have been removed from collection and taxonomy defaults. Canonical URLs are now configured per-entry/term only, since setting a default canonical for an entire collection is not a meaningful SEO configuration.

Entries and terms that inherited the default current canonical type are unaffected — current is now the hardcoded default on the entry/term level.

Renamed Canonical Type and New Term Support

The other canonical type has been renamed to entry. The canonical type field now uses a button group with three options: Current, Entry, and URL. If you reference seo_canonical_type values in code or templates, update other to entry.

Sitemaps

Per-Collection/Taxonomy Settings

The excluded_collections and excluded_taxonomies fields have been removed from the site defaults. The sitemap is now enabled per-collection/taxonomy using the sitemap toggle in the collection/taxonomy config.

Removed Priority and Change Frequency Fields

The Priority and Change Frequency sitemap fields have been removed from entries, terms, and collection/taxonomy defaults. Google and Bing ignore these values. Auto-generated sitemaps no longer output <priority> or <changefreq> XML elements, though the custom sitemaps API still supports them.

Domain Scoping

Each domain now gets its own sitemap index, and its sitemaps only contain URLs from sites on that domain. Previously, a single sitemap index included URLs from all sites regardless of domain.

Setup
Sitemap indexes

example.com, example.com/de, example.com/fr

One index on example.com (unchanged)

example.com, example.com/de, example.fr

One index on example.com, one on example.fr

example.com, example.de, example.fr

One index per domain

Hreflang tags are unaffected and continue to reference all localized versions across domains.

Troubleshooting

If the automated upgrade script fails or doesn't run, you can trigger it manually using Statamic's built-in command. Pass any version below 3.0.0 as the version you are upgrading from:

Last updated