Schema Scope
Schema Scope lets an administrator paste a finished block of JSON-LD and say where it should appear: on every page of the site, or only on selected nodes.
It is built for the situation where an SEO consultant or a client hands over structured data that is already written, and it simply needs to go live on the right pages — without first mapping every Schema.org property onto a field.
Schema Scope lets an administrator paste a finished block of JSON-LD and say where it should appear: on every page of the site, or only on selected nodes.
It is built for the situation where an SEO consultant or a client hands over structured data that is already written, and it simply needs to go live on the right pages — without first mapping every Schema.org property onto a field.
Features
Each schema entry is a separate configuration entity holding one block of JSON-LD together with the rule that decides where it is printed. Two scopes are available:
- Global — the entry is printed on every front-end page. An optional exclusion list names the nodes that should not receive it, which is useful when one landing page already carries its own schema.
- Page specific — the entry is printed only on the nodes selected with an autocomplete field.
What enabling this module adds:
- Markup at the end of
<head>, after the CSS and the JavaScript, rather than at the top wherehook_page_attachments()places its output. - Deploy safe targeting — selected and excluded nodes are stored by UUID rather than by node ID, so configuration exported from a development site keeps pointing at the same content on production, where node IDs may differ.
- Fully exportable — entries travel with
drush cexanddrush cimlike any other configuration. - Validation on save — invalid JSON is rejected with the parser message, a
<script>wrapper that was copied along with the JSON is removed automatically, and the JSON is stored pretty printed so that it stays readable when the entry is edited later. - Safe output — angle brackets and ampersands are escaped as JSON unicode sequences, so stored content cannot close the script element early.
- Theme independent — no template override and no change to
html.html.twig. - Administration pages never receive schema markup.
- Every element carries a
data-schema-scopeattribute holding the machine name of the entry, which makes entries easy to tell apart when reading the page source.
Typical use cases:
- An Organization or WebSite block that belongs on every page of the site.
- A Product, Service or FAQPage block written for one specific landing page.
- A sitewide block that must be suppressed on a handful of pages that carry their own, more specific schema.
- Structured data supplied by an external SEO agency that has to be published without a code deployment.
Post-Installation
There is no new content type and no field to add. Everything is managed from one administration page.
- Grant the Administer Schema Scope permission at
/admin/people/permissions. Grant it to trusted roles only, because the stored JSON is printed as raw markup. - Go to Configuration › Search and metadata › Schema Scope (
/admin/config/search/schema-scope). - Select Add schema, give the entry a name for administrators, choose the scope, and paste the JSON-LD. For the page specific scope, start typing a node title and pick it from the autocomplete; separate several nodes with commas.
- Save. The listing shows every entry with its scope, how many pages it covers, and whether it is enabled.
To confirm the result, open a front-end page in a private browser window and view the source. Each entry appears as its own <script type="application/ld+json" data-schema-scope="…"> element immediately before the closing </head> tag.
Special considerations:
- The markup is inserted by a response event subscriber, so run
drush crafter installing or updating the module. - Entries can be disabled instead of deleted. A disabled entry is not printed and keeps its JSON for later.
- Cached pages are invalidated automatically whenever an entry is saved or deleted.
- The module validates that the JSON parses and that it is an object or an array of objects. It does not validate the content against the Schema.org vocabulary; use the Google Rich Results Test or the Schema.org validator for that.
Additional Requirements
None. This module requires no libraries, no external APIs and no contributed modules. It depends on the core Node module, which is used for the node selection and exclusion fields.
Recommended modules/libraries
- Schema.org Metatag — complementary rather than competing. Use it for structured data that should be generated from field values, and Schema Scope for blocks that arrive finished and are pasted as written. Schema Scope adds its own script elements and does not touch any that another module produces, so both can run on the same site.
- Metatag — for the rest of a site's SEO metadata, which this module deliberately leaves alone.
Similar projects
Several modules add JSON-LD to Drupal. They differ mainly in where the structured data comes from and in how the target pages are chosen.
- Schema.org Metatag builds Schema.org output from your field values through Metatag. Choose it when the data already lives in fields. Schema Scope is for markup that arrives finished and is stored as written.
- JSON-LD Schema Injector also offers a sitewide block and targets further pages by URL path pattern, including wildcards. Choose it if path patterns fit your site better. Schema Scope targets content by selecting nodes instead, which survives a change of URL alias, and it adds a per-node exclusion list for the sitewide entry.
- LD JSON Schema stores schema in a Metatag field on the node edit form and adds rules for views and custom routes. Choose it if you want editors to manage schema on the node itself. Schema Scope keeps every entry in one administrative list and does not depend on Metatag.
Supporting this Module
There is no funding link for this project. The most useful support is a test on your own site and a report in the issue queue — bug reports, patches and reviews are all welcome.
Community Documentation
The README in the repository covers installation, configuration and how the markup is placed. There is no video walkthrough or demo site yet.
How it works
Attachments added through hook_page_attachments() end up at the top of the <head> element, before the CSS and the JavaScript, and a weight cannot move them past it. Schema Scope therefore inserts its markup from a response event subscriber instead: it collects the enabled entries that apply to the page being rendered and inserts one script element per entry immediately before the closing </head> tag. This works with every theme and needs no template change.
Known limitations
- The page specific scope matches node pages only. Pages served by Views, or a front page that is not a node, can currently be covered by a global entry only.
- A node that is deleted leaves its UUID behind in the entry. This is harmless, because a UUID that no longer resolves to a node is ignored, but it is not cleaned up automatically.
Roadmap
- Optional path pattern targeting (
<front>,/news,/blog/*) so that pages served by Views can be targeted as well. - Drupal 12 support once it is released.
Depends on
Dependencies of the latest stable release
- node Drupal core
Required by
Tracked projects that depend on this one
No tracked projects depend on this one yet.