agentsclimarketplace

Rankmath schema integration

Skill Lonsdale201/wp-agent-skills/rankmath/rankmath-schema-integration

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.From its SKILL.md

Install
npx -y skills add Lonsdale201/wp-agent-skills --skill rankmath-schema-integration

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.6 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

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

NeedHookGuidance
inspect or change the complete graphrank_math/json_lduse priority 100 after built-ins
modify a stored schema entity by typerank_math/snippet/rich_snippet_{type}_entityreceives one entity
replace Rank Math's stored type processingrank_math/snippet/rich_snippet_{type}short-circuit contract; avoid unless necessary
final post-validation cleanuprank_math/schema/validated_datapreserve an array; validation already ran
breadcrumb entity onlyrank_math/snippet/breadcrumbreturn the entity array
disable breadcrumb Schemarank_math/json_ld/breadcrumbs_enabledreturn false, scoped if needed
control taxonomy graphrank_math/snippet/remove_taxonomy_databoolean 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

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:

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

What ships with it: 1 file

232 B alongside SKILL.md

agents/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.