This Statamic addon provides a powerful and flexible way to add structured data (JSON-LD) to your Statamic website. It allows you to define structured data templates and automatically inject them into your pages, improving your site's SEO and making your content more understandable for search engines.
- π Dynamic JSON-LD generation based on entry, term, and Runway model data
- π Template-based structured data configuration
- π¦ Built-in schema presets (WebSite, WebPage, Organization, Article, LocalBusiness)
- π― Support for multiple schemas per page
- π Antlers template parsing support
- π§© Support for replicator-to-JSON-LD field mapping
βοΈ Optional Runway resource support- π Coverage & completeness reports in the Control Panel and via CLI
- πͺ Flexible and extensible architecture
- PHP ^8.4 or ^8.5
- Laravel ^12.0
- Statamic ^6.0
You can install this addon via Composer:
composer require justbetter/statamic-structured-dataAfter installing make sure to load the Structured Data tag in your head.
Blade:
{!! Statamic::tag('structured-data:head')->fetch() !!}Antlers
{{ structured-data:head }}Make sure to publish the config by running:
php artisan vendor:publish --tag=justbetter-structured-dataYou can now find the config file at config/justbetter/structured-data.php.
After publishing the config, you can configure:
- which collections support structured data templates
- which taxonomies support structured data objects
- which Runway resource handles should use structured data templates
- whether presets are enabled
- which default presets are available
- custom preset paths
- report storage driver (
fileby default, oreloquent), path, retention, and queue
For Eloquent report storage, run migrations after switching the driver:
php artisan migrateThe addon can generate coverage and completeness reports so you can see:
- Coverage β which published entries/terms are missing an expected
apply_automaticallytemplate (error) - Completeness β which assigned templates (automatic or manual) resolve empty fields after Antlers parsing (error)
- Warnings β published items in a scoped collection/taxonomy that has templates, but the item has none assigned
- Runway β incompleteness for resources that have a template (no missing/warning for Runway)
- Summary scores: clean %, coverage %, completeness %, plus per-scope cards
Open Tools β JustBetter β Structured Data Reports (requires the view structured data reports permission).
From there you can generate a report for the selected site, browse previous runs, inspect scores/charts, filter errors vs warnings, open edit links, and use the Schema Markup Validator helpers (copy JSON-LD / open validator).
# Generate a report for the default/selected site
php artisan structured-data:report
# Limit to one site / template
php artisan structured-data:report --site=default --template=TEMPLATE_ID
# JSON output (useful for CI)
php artisan structured-data:report --json --fail-on-issues
# Also fail when warnings are present
php artisan structured-data:report --fail-on-warnings
# Dispatch to the queue (runs sync when QUEUE_CONNECTION=sync)
php artisan structured-data:report --queueSchedule it when needed:
Schedule::command('structured-data:report --site=default')->daily();Templates have an Apply automatically toggle. When enabled, new entries/terms in the targeted collection/taxonomy receive that template on create. The report treats only those templates as expected for coverage. Use the existing Apply Template action to attach templates to existing content.
Create templates in your Statamic control panel that define your structured data schemas. Each template can contain multiple schema definitions with:
- Special properties (@context, @type, @id)
- Custom fields with various data types (strings, numeric, arrays, objects)
- Dynamic values using Antlers templating syntax
In your entry or term's content, you can assign one or more structured data templates using the structured_data_templates field. The addon will automatically process these templates and generate the appropriate JSON-LD scripts.
Runway is soft-optional. When statamic-rad-pack/runway is installed, templates can target a Runway resource (blueprint_type: runway + use_for_runway). Those templates apply to all models of that resource at render time β there is no per-model template picker.
Enable resources in config:
'runway' => [
'product',
'category',
],For projects that use Runway frontend routing, structured-data:head resolves the current model via Runway URI lookup.
For Magento/Rapidez-style routes (or any custom routing), pass the current model explicitly:
Blade:
@isset($product)
{!! Statamic::tag('structured-data:for')->param('item', $product)->param('resource', 'product')->fetch() !!}
@endisset
{!! Statamic::tag('structured-data:head')->fetch() !!}The optional resource param forces the Runway handle when the storefront model class differs from the Runway model class.
Available variables for Runway templates include blueprint fields plus model attributes/appends.
Render the generated JSON-LD where you need it in your layout:
Blade:
{!! Statamic::tag('structured-data:head')->fetch() !!}Antlers:
{{ structured-data:head }}Here's an example of how you might structure a basic Organization schema:
{
"specialProps": {
"context": "https://schema.org",
"type": "Organization",
"id": "https://example.com"
},
"fields": [
{
"key": "name",
"type": "string",
"value": "{{ company_name }}"
},
{
"key": "url",
"type": "string",
"value": "{{ config:app:url }}"
}
]
}Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.