Rankmath plugin compatibility
Skill Lonsdale201/wp-agent-skills/rankmath/rankmath-plugin-compatibility
A community-maintained collection of agent skills for WordPress plugin and theme development.
npx -y skills add Lonsdale201/wp-agent-skills --skill rankmath-plugin-compatibilityAssembled 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.
What its author says it does
Copied from the file, not written here
Build or review optional Rank Math compatibility in third-party WordPress plugins and themes: bootstrap safely around rank_math/loaded, expose public CPTs and taxonomies, filter SEO title, description, robots, canonical and social metadata, register replacement variables, feed custom editor fields into content analysis, and support headless output. Use for Rank Math integrations, compatibility layers, custom content models, SEO metadata imports, rank_math/frontend/* or rank_math/opengraph/* hooks, rank_math_register_var_replacement(), and rank_math_content JavaScript filters. Do not use for JSON-LD graph design or sitemap providers; use the focused sibling skills.
SKILL.md
10.0 KB, as published. Nobody here has run it
Rank Math plugin compatibility
Implement a soft, hook-based compatibility layer that keeps working when Rank Math is absent or a module is disabled. Prefer WordPress and documented Rank Math hooks over internal containers, direct output, or copied plugin logic.
Workflow
- Identify the content surface: singular CPT, taxonomy archive, virtual route, editor-only field, headless URL, or imported SEO metadata.
- Confirm whether Rank Math is optional or a declared dependency. Keep it optional unless the product explicitly cannot function without it.
- Register integration hooks early and idempotently.
- Make frontend output and editor analysis agree, but do not confuse them: frontend PHP filters do not update the editor score, and editor JavaScript filters do not alter frontend tags.
- Verify rendered HTML, not only stored meta or callback execution.
- Test once with Rank Math active and once inactive.
Bootstrap safely
rank_math/loaded fires while the Rank Math plugin file is loading, before its plugins_loaded:14 initialization and before modules load on after_setup_theme:2. Handle both plugin load orders:
function acme_rank_math_boot(): void {
static $booted = false;
if ( $booted || ! defined( 'RANK_MATH_VERSION' ) ) {
return;
}
$booted = true;
add_filter( 'rank_math/frontend/title', 'acme_rank_math_title' );
}
if ( did_action( 'rank_math/loaded' ) ) {
acme_rank_math_boot();
} else {
add_action( 'rank_math/loaded', 'acme_rank_math_boot' );
}
Apply these rules:
- Do not call
rank_math()beforerank_math/loaded. - Do not assume
rank_math/loadedmeans active modules are instantiated. Check module-dependent classes afterafter_setup_themepriority 2, or simply register their hooks and let inactive modules leave them unused. - Use
RankMath\Helper::is_module_active( 'rich-snippet' )for Schema and'sitemap'for XML sitemaps only when the helper exists. The Schema module ID is notschema. - Do not instantiate Rank Math frontend, Paper, Schema, or Sitemap classes yourself during normal requests.
- Do not edit Rank Math files or load files from
RANK_MATH_PATHmanually; its Composer autoloader owns those classes.
Make custom content discoverable
For a normal CPT or taxonomy, fix the WordPress registration before adding SEO overrides:
- Register indexable CPTs as
publicandpublicly_queryable, with stable rewrites and canonical permalinks. - Register public taxonomy archives so
is_taxonomy_viewable()succeeds. - Ensure singular and archive requests set the main query conditionals correctly. Rank Math chooses its Paper implementation from those conditionals.
- Treat
rank_math/excluded_post_typesandrank_math/excluded_taxonomiesas list filters, despite their names. Preserve the array shape. - Use
rank_math/metabox/add_seo_metaboxonly for UI visibility. It does not make content indexable. - Do not force private, capability-protected, duplicate, search-only, or noncanonical objects into Rank Math.
Filter frontend metadata
Use the narrowest output filter and preserve its return type:
| Need | Hook | Return |
|---|---|---|
| document title | rank_math/frontend/title | string |
| meta description | rank_math/frontend/description | string |
| robots directives | rank_math/frontend/robots | associative array |
| advanced robots | rank_math/frontend/advanced_robots | associative array |
| canonical URL | rank_math/frontend/canonical | string/false |
| Open Graph type | rank_math/opengraph/type | string |
| Facebook image URL | rank_math/opengraph/facebook/image | string |
| Twitter image URL | rank_math/opengraph/twitter/image | string |
| Twitter card type | rank_math/opengraph/twitter/card_type | string |
Scope every callback to the intended query:
function acme_rank_math_robots( array $robots ): array {
if ( ! is_singular( 'acme_document' ) || ! acme_is_public_document() ) {
return $robots;
}
$robots['index'] = 'index';
$robots['follow'] = 'follow';
return $robots;
}
add_filter( 'rank_math/frontend/robots', 'acme_rank_math_robots' );
Do not append a second <title>, canonical, robots tag, Open Graph block, or JSON-LD script on wp_head. Modify the owner plugin's value instead. Rank Math memoizes Paper values during a request, so register filters before wp/rank_math/head and keep callbacks deterministic. Returning an empty canonical removes its output; do that only for a deliberate no-canonical response.
Register replacement variables
Register variables on the dedicated action. Use a globally unique ID and return, never echo, the replacement:
add_action( 'rank_math/vars/register_extra_replacements', static function (): void {
rank_math_register_var_replacement(
'acme_reference',
[
'name' => __( 'Document reference', 'acme' ),
'description' => __( 'Current document reference.', 'acme' ),
'variable' => 'acme_reference',
'example' => 'DOC-1042',
],
static function ( array $var_args, $object ): string {
$post_id = $object instanceof \WP_Post ? $object->ID : get_queried_object_id();
return (string) get_post_meta( $post_id, '_acme_reference', true );
}
);
} );
Set 'nocache' => true only for genuinely request-varying values. Do not use a user-specific, random, time-varying, or secret value in public SEO metadata.
Feed custom fields into content analysis
The editor analyzer is separate from frontend metadata. Enqueue only on relevant editing screens with dependencies wp-hooks and rank-math-analyzer, then return plain analyzable text:
wp.hooks.addFilter( 'rank_math_content', 'acme/seo', ( content ) => {
const field = document.querySelector( '#acme-summary' );
return field ? `${ content } ${ field.value }` : content;
}, 20 );
On field changes, debounce rankMathEditor.refresh( 'content' ). Never include hidden authorization data, secrets, raw JSON blobs, shortcodes that execute side effects, or unbounded HTML. The official documentation also names rank_math_title, but the distributed 1.0.273 build inspected for this skill did not expose a verifiable wp.hooks.applyFilters( 'rank_math_title', ... ) call. Re-check the installed build before relying on that hook.
Persist metadata only when required
Prefer runtime filters for computed values. For an explicit import or migration, core metadata writes such as update_post_meta( $post_id, 'rank_math_title', $value ) can be appropriate, but:
- validate authorization and object ownership before accepting external values;
- preserve structured types such as the
rank_math_robotsarray; - distinguish absent, empty, inherited, and intentionally cleared values;
- avoid direct SQL so metadata caches and hooks remain coherent;
- do not read Rank Math metadata and then overwrite it later in the same request after Paper has memoized the old value;
- never overwrite administrator-authored SEO fields on every save unless that ownership contract is explicit.
Headless compatibility
When Rank Math headless support is enabled, GET /wp-json/rankmath/v1/getHead?url=<internal-url> builds the same rank_math/head output after reconstructing the WordPress query. Ensure custom rewrites and query conditionals work in a fresh internal request. Do not expose an alternative unauthenticated URL-fetch proxy; Rank Math validates that the requested URL belongs to the site.
Verification
- Request a representative singular, archive, paginated, noindex, password-protected, and 404 URL.
- Assert exactly one title, description, robots tag, canonical, Open Graph set, and Schema script where applicable.
- Confirm canonical URLs are absolute and agree with sitemap URLs.
- Confirm robots arrays contain keyed directives such as
['index' => 'noindex'], not a numeric list. - Edit the custom field and verify the analyzer refreshes without changing saved content unexpectedly.
- Disable Rank Math and confirm the host plugin neither fatals nor emits duplicate fallback SEO unless that fallback is intentional.
Cross-references
- Use
rankmath-schema-integrationfor JSON-LD graph entities and Schema.org relationships. - Use
rankmath-sitemap-integrationfor XML sitemap inclusion, exclusion, providers, and invalidation. - Use
wp-security-auditwhen metadata or custom editor fields accept request data.
What this skill does not cover
- Rank Math PRO-only APIs unless their source is also available and tested.
- Search ranking guarantees, keyword strategy, or editorial SEO advice.
- Direct modification of Rank Math internals, database tables, or settings UI.
References
- Official documentation: https://rankmath.com/kb/filters-hooks-api-developer/
- Official documentation: https://rankmath.com/kb/content-analysis-api/
- Official documentation: https://rankmath.com/kb/make-theme-rank-math-compatible/
- Verified source paths:
rank-math.phpincludes/frontend/paper/class-paper.phpincludes/opengraph/includes/replace-variables/class-manager.phpincludes/template-tags.phpincludes/rest/class-headless.phpassets/admin/js/custom-fields.js