WORDPRESS
How to Audit Missing Polylang Translations in WordPress
Find missing Polylang translations, audit language coverage and check translation links safely with four read-only WordPress Abilities.
FREE WORDPRESS PLUGIN
Multilingual Abilities
Inspect missing Polylang translation links and bounded language coverage without changing your posts or translation groups.
- Install with Polylang on WordPress 6.9+
- Check Tools → Multilingual Abilities
- Run a permission-aware, bounded audit
Read-only and administrator-gated. No translation, automatic link repair, background scan or bundled MCP server. Coverage is paginated by source posts, not a site-wide total. External REST exposure stays off unless explicitly enabled.

Missing a French translation in Polylang? First check whether the English source post has a linked French post, whether the linked post is published, and whether the post type is enabled for translation. Those are different problems. A blank language-switcher link or a low translation count does not, by itself, tell you which one happened.
This guide shows a repeatable, read-only way to inspect those differences with ModelGain Multilingual Abilities 0.1.0. You will get exact input examples, a worked pagination case, a troubleshooting decision guide and a human-review checklist. The free WordPress.org plugin does not create translations, change relationships, publish drafts or run a site-wide background scan.
Quick answer: which failure are you actually seeing?
- There is no linked target post: the missing-translations ability can identify an absent language link within the source posts it scans. First confirm that translation is actually required.
- A target post exists but is a draft: the coverage audit distinguishes unpublished targets from absent ones. A translation link alone does not make a page public.
- A translation appears to point to the wrong post or language: the link check reports only anomalies provable from Polylang’s exposed post relationships. An editor must verify the intended counterpart.
- Nothing is returned, or the post type is unavailable: confirm Polylang, language configuration, supported post types and permissions before concluding the content is complete.
Polylang does not require every post to be translated. It manages separate posts and their relationships; a missing translation is an editorial finding, not automatically a software defect. See Polylang’s guide to translating posts and pages.
Before you start: exact requirements and safe access
- Use WordPress 6.9+ and PHP 7.4+, with Polylang active and languages configured. Use maintained runtime versions in production; a declared minimum is not a security recommendation.
- Install and activate ModelGain Multilingual Abilities 0.1.0. It is a separate integration and is not affiliated with Polylang.
- Open Tools → Multilingual Abilities. Check provider availability, language readiness, supported post types and registration status. This is a diagnostic/settings screen, not a one-click report or translation editor.
- Use a trusted administrator-level WordPress execution context to invoke the abilities. Execution requires
manage_options; individual source and target posts are also subject to editing-permission checks. - Leave External REST exposure off for local PHP/WP-CLI use. Turn it on only if a reviewed external client needs it, with appropriate WordPress authentication and access controls.
The plugin provides four native WordPress Abilities; it does not ship a standalone MCP server, translation service, chatbot or scheduled scanning UI. For a developer who already uses the WordPress CLI, the simplest local inspection path is WP_Ability::execute(). WordPress documents this in its official Abilities PHP reference.
1. Confirm your exact language slugs
Language names and configured slugs are different. For example, the site might display “French”, while an ability expects fr; never guess the available languages from a menu label.
On a WordPress installation you administer, run this read-only command from a trusted shell where WP-CLI is already installed. Replace YOUR_ADMIN_USERNAME with an existing administrator account; it is an example identifier, not a credential.
wp --user=YOUR_ADMIN_USERNAME eval '
$ability = wp_get_ability( "modelgain-multilingual/list-languages" );
if ( ! $ability ) { WP_CLI::error( "Ability is not registered" ); }
$result = $ability->execute();
if ( is_wp_error( $result ) ) {
WP_CLI::error( $result->get_error_message() );
}
WP_CLI::log( wp_json_encode( $result, JSON_PRETTY_PRINT ) );
'
Read the returned default_language and the languages array, then choose one source language and a different target language. An unconfigured slug or identical source and target is an invalid audit request, not evidence that the translation disappeared. If the ability is unavailable, see how to separate a missing WordPress Abilities API from failed registration.

2. Find missing links for one source language and post type
Use modelgain-multilingual/find-missing-translations when the question is “Which English posts have no linked French post?” The required inputs are source_language, target_language and post_type. The optional offset and limit control how many source-language posts are inspected per request. The limit cannot exceed 100.
The following example checks the first 50 English WordPress posts for a missing French relationship; it does not create or modify anything:
wp --user=YOUR_ADMIN_USERNAME eval '
$ability = wp_get_ability(
"modelgain-multilingual/find-missing-translations"
);
if ( ! $ability ) { WP_CLI::error( "Ability is not registered" ); }
$result = $ability->execute( array(
"source_language" => "en",
"target_language" => "fr",
"post_type" => "post",
"offset" => 0,
"limit" => 50,
) );
if ( is_wp_error( $result ) ) {
WP_CLI::error( $result->get_error_message() );
}
WP_CLI::log( wp_json_encode( $result, JSON_PRETTY_PRINT ) );
'
The response includes an items list of missing target relationships, a count of returned findings, has_more, and next_offset. For each finding you can inspect the source ID, status, safe URL and target-language indicator. The plugin does not return full article bodies or translated text.
Do not infer that an existing French draft is “missing” just because it is not publicly visible. A linked draft should be investigated as a publication-status issue using the next audit, not automatically scheduled for retranslation.
3. The important pagination trap: zero missing results can still mean more work
Consider an illustrative site with 205 English source posts. Assume the first 100 have linked French translations, while later posts include gaps. The first response could have count: 0 and items: [], while still reporting has_more: true and next_offset: 100. These numbers are an invented teaching fixture, not a measurement from a live site.
{
"source_language": "en",
"target_language": "fr",
"post_type": "post",
"offset": 0,
"limit": 100,
"count": 0,
"has_more": true,
"next_offset": 100,
"items": []
}
Here, count means missing translations found on that source page, not the number of English posts inspected. Continue with offset: 100 and the same language/post type/limit. If that response still has has_more: true, follow its next_offset again. Stop only when has_more is false, or document that you intentionally performed only a sample.
Never advance the offset by count or the length of items. Those measure findings; pagination follows source posts scanned. Content may change while a multi-page scan is running, so treat the aggregated result as an operational snapshot, not a transactionally consistent site-wide report.
4. Measure coverage without confusing “linked” with “published”
Run modelgain-multilingual/audit-language-coverage with source_language, post_type, offset and limit. Unlike the missing-target audit, this ability evaluates configured languages for each scanned source post; it does not take a required target_language input.
$ability = wp_get_ability(
'modelgain-multilingual/audit-language-coverage'
);
$result = $ability->execute( array(
'source_language' => 'en',
'post_type' => 'post',
'offset' => 0,
'limit' => 50,
) );
The output includes scanned_count, by_language, per-source coverage states and pagination markers. Review linked, unpublished, absent, inaccessible and invalid separately. An inaccessible translation is not equivalent to a missing post; an unpublished translation is not necessarily ready for a visitor. Only interpret the states against the actual user permissions and current Polylang post records.
For an editorial review, record the source-language filter, post type, scan start time, offsets examined and number of source posts processed. If you need an aggregate across batches, label it explicitly as your own aggregation of bounded responses. The plugin does not promise an always-current global coverage percentage, historical trend dashboard or scheduled report.
5. Check translation relationships without rewriting them
Use modelgain-multilingual/check-translation-links for a bounded set of source posts when you suspect a structural inconsistency. Its input is the same as the coverage audit: source_language, post_type, offset and limit. Check the anomalies for each source_id and correlate them with the Polylang editor.
Polylang’s public function reference documents pll_get_post_translations() for language-to-post mappings and pll_get_post_language() for a post’s assigned language. The audit plugin uses public provider information and deliberately avoids asserting speculative orphan relationships or detecting the *language of the text itself*. An apparent mismatch is a prompt for review, not authorization to relink content automatically.
If a post is truly linked to the wrong target, verify both IDs and their intended editorial roles in WordPress first. Use Polylang’s own UI for any manual correction, ideally after a suitable backup. Never bulk-repair relationships based only on a diagnostic flag.
6. Troubleshoot the actual failure instead of guessing
These situations lead to different next actions. The guide below is an editorial decision aid; it does not inspect your WordPress installation or execute any plugin operation.
Polylang missing translation: choose the correct check
Applies when: An administrator is diagnosing an absent target-language post, a draft target, a translation relationship anomaly, or an inaccessible/unavailable WordPress Ability.
Quick answer
First establish a configured source language, a supported post type and authorized execution. Then distinguish no linked target, linked-but-unpublished target, a provable inconsistent group mapping, and a provider/permission error. The ModelGain plugin can only report evidence; it never performs fixes.
What to do
-
Check WordPress 6.9+, configured Polylang languages, a Polylang-enabled post type, and a trusted administrator context. Keep external REST exposure disabled unless needed.
-
Use list-languages, find-missing-translations, audit-language-coverage or check-translation-links. Supply explicit language and post-type inputs. Each page covers at most 100 source posts.
-
Verify the source ID, language relationship and publication state in Polylang. Continue pagination when has_more is true; do not interpret a zero-finding page as proof of whole-site completeness.
Which result or symptom do you have?
All paths are listed below. Select a symptom to focus on the most relevant path.
Verify a required content gap
Run find-missing-translations for one source and target language, then follow next_offset while has_more is true. A missing link is not proof that translating the item is required; check editorial scope before assigning work.
Separate link existence from readiness
Use audit-language-coverage to distinguish unpublished from absent targets. Inspect the linked translation in the WordPress editor; do not create another translation or publish content without editorial review.
Check what the mapping can prove
Use check-translation-links and verify both language assignments and IDs against the Polylang editor. Do not treat content similarity as a reliable link or automatically rewrite translation relationships.
Classify availability, exposure and permission separately
Confirm the core Abilities API and provider first. Registered internal abilities may be intentionally hidden from REST. External discovery requires an explicit opt-in and an authenticated caller with manage_options; do not weaken role checks.
Did this help?
For custom post types, first check Languages → Settings → Custom post types and Taxonomies in Polylang. A non-enabled post type is outside this plugin’s content audit scope. See Polylang’s CPT configuration guidance. For a translated URL returning 404, investigate the actual permalink/routing configuration separately rather than treating the missing-translation audit as an SEO crawler.
If an ability exists in PHP but is not listed over REST, that can be deliberate: WordPress abilities are hidden from REST by default. This plugin preserves that default until its External REST exposure setting is explicitly enabled. Even then, the caller must authenticate and pass the ability’s administrator-level permission check. For a distinct MCP problem, follow the registration versus MCP-discovery troubleshooting guide.
7. Turn findings into a useful editorial backlog
Once you have validated a representative set of findings, assign each one a decision. You can store this in an ordinary team spreadsheet or ticket queue without adding a new WordPress integration:
- Required translation missing: record source URL/ID, target language, content owner, business priority and expected delivery.
- Linked but unpublished: record the translation ID and the editorial review or approval required; do not commission a duplicate translation.
- Intentionally untranslated: mark the exception; do not inflate a “broken content” count.
- Link anomaly: independently verify both posts, preserve the intended group and only then plan a manual Polylang correction.
- Not auditable: record an unsupported post type, insufficient permission or missing provider as a technical prerequisite, not a translation deficit.
For a practical acceptance test, choose five known examples: one linked published translation, one absent link, one linked draft, one intentionally untranslated article and one access-limited source. Compare the plugin result against Polylang’s editor. Then scan two successive source pages and confirm that offsets, has_more and next_offset behave as expected. A real production corpus may contain content that changes during the audit; document those limitations.
What this plugin does not audit
ModelGain Multilingual Abilities 0.1.0 does not generate translations, translate strings/menus, set language assignments, repair links, validate live hreflang output, check sitemaps, fix 404 URLs, assess translation quality, expose private content to anonymous visitors, schedule background jobs or operate an AI model. It supports Polylang’s public APIs and does not require Polylang Pro; separate Pro-specific integration testing has not been completed. Do not confuse Polylang Pro REST translation features with this WordPress Abilities integration.
Next step: if you administer a compatible Polylang site and need repeatable read-only content checks, review the ModelGain Multilingual Abilities product page and official installation, changelog and support listing. If you only want to create or edit translations, use Polylang’s built-in translation workflow instead.