Add, extend, remove, or audit Schema.org JSON-LD generated by Rank Math from a third-party WordPress plugin. Use when code touches rank_math/json_ld, rank_math/schema/validated_data, rank_math/snippet/rich_snippet_*_entity, custom post types with structured data, WooCommerce Product schema extensions, entity @id links, schema duplication, or custom event, service, course, job, person, organization, FAQ, and breadcrumb entities. Covers final graph mutation, stable identifiers, entity relations...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Lonsdale201/wp-agent-skills --skill rankmath-schema-integration --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Rankmath Schema Integration?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lonsdale201-rankmath-schema-integration)More formats (shields.io, HTML) on the badges page.
---
name: rankmath-schema-integration
description: >-
Add, extend, remove, or audit Schema.org JSON-LD generated by Rank Math from a third-party WordPress plugin. Use when code touches rank_math/json_ld, rank_math/schema/validated_data, rank_math/snippet/rich_snippet_*_entity, custom post types with structured data, WooCommerce Product schema extensions, entity @id links, schema duplication, or custom event, service, course, job, person, organization, FAQ, and breadcrumb entities. Covers final graph mutation, stable identifiers, entity relationships, execution order, module guards, validation, and duplicate avoidance; it does not cover XML sitemaps or general title/meta filters.
metadata:
wp-skills-author: "Soczó Kristóf"
wp-skills-contact: "mailto:lonsdale201@hotmail.com"
wp-skills-plugin: "seo-by-rank-math"
wp-skills-plugin-version-tested: "1.0.273"
wp-skills-wp-version-tested: "7.0.1"
wp-skills-php-min: "7.4"
wp-skills-last-updated: "2026-07-13"
---
# Rank Math Schema integration
Extend Rank Math's single JSON-LD `@graph` instead of printing a competing script. Preserve graph relationships, administrator-authored entities, and Rank Math's associative working keys.
## Workflow
1. Define the eligible WordPress query and authoritative data source.
2. Inspect the graph Rank Math already generates for that query.
3. Decide whether to extend an existing entity, add a connected entity, or remove an entity. Prefer extension over duplication.
4. Register a narrowly scoped filter and preserve the graph on every early return.
5. Validate semantic requirements, references, dates, URLs, and duplicate types.
6. Compare the rendered JSON-LD with and without the integration.
## Choose the correct hook
| Need | Hook | Guidance |
|---|---|---|
| inspect or change the complete graph | `rank_math/json_ld` | use priority 100 after built-ins |
| modify a stored schema entity by type | `rank_math/snippet/rich_snippet_{type}_entity` | receives one entity |
| replace Rank Math's stored type processing | `rank_math/snippet/rich_snippet_{type}` | short-circuit contract; avoid unless necessary |
| final post-validation cleanup | `rank_math/schema/validated_data` | preserve an array; validation already ran |
| breadcrumb entity only | `rank_math/snippet/breadcrumb` | return the entity array |
| disable breadcrumb Schema | `rank_math/json_ld/breadcrumbs_enabled` | return false, scoped if needed |
| control taxonomy graph | `rank_math/snippet/remove_taxonomy_data` | boolean plus taxonomy slug |
Rank Math collects the graph through `rank_math/json_ld`, validates it, applies `rank_math/schema/validated_data`, then serializes `array_values( $data )` under one `@context` and `@graph`. Do not call `array_values()` in your filter: later callbacks use associative keys.
## Add a connected entity
```php
add_filter(
'rank_math/json_ld',
static function ( $data, $jsonld ) {
if ( ! is_array( $data ) || ! is_singular( 'acme_event' ) ) {
return $data;
}
$post_id = ! empty( $jsonld->post_id )
? (int) $jsonld->post_id
: get_queried_object_id();
$start = get_post_meta( $post_id, '_acme_start', true );
if ( ! $post_id || ! is_string( $start ) || '' === trim( $start ) ) {
return $data;
}
try {
$start_at = new \DateTimeImmutable( $start, wp_timezone() );
} catch ( \Exception $exception ) {
return $data;
}
$canonical = ! empty( $jsonld->parts['canonical'] )
? $jsonld->parts['canonical']
: get_permalink( $post_id );
if ( ! is_string( $canonical ) || '' === $canonical ) {
return $data;
}
$entity_id = strtok( (string) $canonical, '#' ) . '#acme-event';
$entity = [
'@type' => 'Event',
'@id' => esc_url_raw( $entity_id ),
'name' => wp_strip_all_tags( get_the_title( $post_id ) ),
'url' => esc_url_raw( (string) $canonical ),
'startDate' => $start_at->format( DATE_W3C ),
];
if ( ! empty( $data['WebPage']['@id'] ) ) {
$entity['mainEntityOfPage'] = [ '@id' => $data['WebPage']['@id'] ];
}
$data[ 'acme-event-' . $post_id ] = $entity;
return $data;
},
100,
2
);
```
Use a stable graph key and `@id`; do not use `uniqid()`, request time, array position, translated labels, or random UUIDs generated per render. Derive identifiers from the canonical resource and a stable fragment.
## Extend an existing entity
Do not assume the associative key is `Product`, `Article`, or `richSnippet`. Stored schemas use keys derived from metadata IDs, and `@type` may be an array:
```php
add_filter( 'rank_math/json_ld', static function ( array $data ): array {
if ( ! is_singular( 'product' ) ) {
return $data;
}
foreach ( $data as &$entity ) {
$types = isset( $entity['@type'] ) ? (array) $entity['@type'] : [];
if ( ! in_array( 'Product', $types, true ) ) {
continue;
}
$brand = get_post_meta( get_queried_object_id(), '_acme_brand', true );
if ( is_string( $brand ) && '' !== trim( $brand ) ) {
$entity['brand'] = [
'@type' => 'Brand',
'name' => wp_strip_all_tags( $brand ),
];
}
break;
}
unset( $entity );
return $data;
}, 100 );
```
Preserve an administrator's valid value unless the third-party plugin is explicitly authoritative. Do not add a second Product, Article, BreadcrumbList, Organization, WebSite, or WebPage merely because its expected key was not found.
## Maintain graph integrity
- Add `@context` only at the top-level output. Rank Math owns it; entities should not repeat it.
- Reference entities with `['@id' => $id]`; do not copy the full Organization, WebPage, Person, or ImageObject into every relation.
- Reuse the actual existing entity `@id` when available. Do not guess `/#organization` if the graph says something else.
- Keep URLs absolute and canonical. Strip fragments before adding your own stable fragment.
- Emit ISO 8601 dates with an explicit timezone. Reject unparseable dates instead of producing 1970 values.
- Omit unavailable optional properties. Never invent ratings, review counts, prices, availability, authors, addresses, or identifiers.
- Treat Schema.org vocabulary validity and Google rich-result eligibility as different checks. A valid Schema.org type may not qualify for a Google feature.
- Preserve zero and boolean values intentionally. Rank Math's validation removes empty strings, not every falsy value.
## Respect execution order and caching
Use priority 100 on `rank_math/json_ld` when the integration needs the complete graph; Rank Math's entity connector runs at priority 99. Use a type-specific entity hook when only one stored entity should change.
Keep callbacks pure for the same query. Prime metadata or object caches before loops, avoid remote HTTP calls, and never perform writes from a frontend Schema filter. Full-page caches can retain old JSON-LD after source data changes; invalidate the page cache through the owning cache integration, not by disabling Rank Math Schema.
## Avoid persistence traps
For runtime integration, filter the graph. Do not write `rank_math_schema_*` postmeta directly:
- Rank Math derives schema working keys from `meta_id`, not only `meta_key`.
- its editor stores metadata and shortcode relationships with additional semantics;
- `RankMath\Schema\DB` uses static in-request caches;
- direct SQL bypasses metadata caches and hooks.
If the requirement is to create editor-visible, administrator-editable persisted schemas, use the installed version's supported editor/REST workflow and test round-trip editing. Do not emulate it from inferred meta rows.
## Security and privacy
- Build public Schema only from data allowed on the public page.
- Do not leak private post meta, email addresses, internal IDs, unpublished relations, capability-protected fields, or precise personal locations.
- Do not accept arbitrary caller-supplied JSON-LD and pass it through unchanged.
- Do not rely on Rank Math's final encoding as business-level validation. Validate types, URLs, dates, cardinality, and allowed properties at your boundary.
## Verification
- Capture the `<script type="application/ld+json" class="rank-math-schema">` block and decode it as JSON.
- Assert one top-level `@context`, one `@graph`, unique `@id` values, and resolvable internal `@id` references.
- Test missing optional meta, malformed dates, password-protected posts, drafts/previews, pagination, and a different post type.
- Check that disabling the `rich-snippet` module simply removes integration output without a fatal error.
- Compare classic frontend and Rank Math headless output if headless support is enabled.
- Run a Schema.org validator and the relevant search-engine rich-result test; record warnings separately from errors.
## Cross-references
- Use **`rankmath-plugin-compatibility`** for bootstrap, title, robots, canonical, social metadata, and editor analysis.
- Use **`rankmath-sitemap-integration`** to align canonical/indexability decisions with XML sitemap entries.
- Use **`wp-metadata-api`** if the source data uses complex or multi-row WordPress metadata.
## What this skill does not cover
- Rank Math PRO schema templates or PRO-only types without source and runtime verification.
- XML sitemap generation, IndexNow submission, or ranking strategy.
- Persisting undocumented Rank Math editor internals.
## References
- Official documentation: <https://rankmath.com/kb/filters-hooks-api-developer/>
- Official documentation: <https://schema.org/docs/schemas.html>
- Official documentation: <https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data>
- Verified source paths:
- `includes/modules/schema/class-jsonld.php`
- `includes/modules/schema/class-frontend.php`
- `includes/modules/schema/class-db.php`
- `includes/modules/schema/snippets/`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!