Blog Locale Audit, Multilingual Quality Control
Audits a directory of multilingual blog content to ensure every language
version is complete, consistent, correctly tagged, and SEO-optimized.
Catches international content issues before they hurt rankings.
Adapted from claude-blog-multilingual by Chris Mueller (Pro Hub Challenge,
March 2026). Original: https://github.com/Chriss54/multilingual-int
Workflow
Phase 1: Discovery
- Resolve the target directory inside the project root/current working
directory. Reject symlinked directories and traversal outside the root,
then scan blog content and group posts by language using:
- Subdirectory names (
en/, de/, fr/).
- Frontmatter
lang and translatedFrom fields.
hreflang-map.json if present.
- Normalize detected language codes with the shared multilingual locale rules
used by
blog-translate, blog-localize, and blog-multilingual: ISO
639-1 language in lowercase, optional ISO 15924 script in title case,
optional ISO 3166-1 Alpha-2 region in uppercase. Flag ambiguous
language-only codes such as es, pt, and zh unless the content
declares an explicit neutral mode.
- Build a content matrix mapping which post exists in which languages. Use a
stable translation-group key before comparing slugs:
translationGroupId,
sourceSlug, schema translationOfWork.url, or the IDs and URLs in
hreflang-map.json. Fall back to normalized source slug only when no
stable key exists.
- Detect the source language (most common
translatedFrom target, or the
sourceLanguage field in hreflang-map.json if present).
Phase 2: Completeness Audit
Show which translations are missing:
### Translation coverage matrix
| Post (EN) | DE | FR | ES | JA |
|-----------|----|----|----|----|
| how-to-avoid-ai-slop | ok | ok | missing | missing |
| content-marketing-2026 | ok | missing | ok | missing |
Coverage: 60% (6 of 10 expected translations present)
Missing: 4 translations needed
Phase 3: Content Parity Audit
For every post that exists in multiple languages:
| Check |
What |
Severity |
| Section count |
Same number of H2 and H3 sections |
Critical |
| FAQ count |
Same number of FAQ items |
High |
| Image count |
Same number of images |
High |
| Chart count |
Same number of charts (SVG figures) |
High |
| Word count ratio |
Within expected band for language pair (DE +20% to +30%, JA -20%, ES +10%) |
Medium |
| Link count |
Similar internal and external link counts |
Medium |
| Evidence-backed claims |
Same supported claims and citations across versions |
Medium |
| Frontmatter parity |
All required fields present per version |
High |
Flag every significant deviation as an issue.
Phase 4: SEO Parity Audit
For every language version verify:
| Element |
Check |
Severity |
| Title tag |
Present, localized, clear, and appropriate for the page |
Critical |
| Meta description |
Present, localized, accurate, and consistent with visible content |
Critical |
lang attribute or frontmatter lang |
Present, valid Google-compatible hreflang or BCP 47 language tag |
Critical |
| Canonical URL |
Points to the same-language page, not the source-language page or x-default |
Critical |
Schema inLanguage |
Matches lang |
High |
Schema translationOfWork |
Points to the source URL |
High |
| Alt text |
Translated (no English alt in non-EN posts) |
High |
| Slug |
Localized (no English slug in non-EN posts) |
Medium |
| Tags |
Localized |
Medium |
| Keywords |
Localized |
Medium |
Phase 5: Hreflang Audit
If hreflang-tags.html, hreflang-sitemap.xml, or hreflang-map.json
exists in the directory:
| Check |
What |
Severity |
| Self-referencing |
Each page references itself |
Critical |
| Return tags |
Every relationship is bidirectional |
Critical |
| Canonical consistency |
Every hreflang page canonicalizes to its same-language URL |
Critical |
x-default |
Present, points to the unmatched-language fallback such as a language selector or default market page |
Critical |
| Language codes |
Valid Google-compatible hreflang tags: ISO 639-1 language plus optional ISO 15924 script or ISO 3166-1 Alpha-2 region |
High |
| URL consistency |
Same protocol, same trailing-slash convention |
Medium |
| Completeness |
Every language version represented |
High |
If no hreflang files exist, report it as a critical gap and offer:
"Run /blog multilingual <topic> --languages ... to regenerate, or create
hreflang-tags.html manually."
If seo-hreflang from claude-seo is installed, suggest running it for
deeper validation.
Phase 6: Freshness Audit
For posts with translatedDate in frontmatter:
| Check |
What |
Severity |
| Source updated after translation |
Source modified after translatedDate |
Critical |
| Source content drift |
Stored source hash or source dateModified differs from current source |
Critical |
| Translation drift |
Stored translation hash differs from current localized file |
Medium |
| Translation older than 90 days |
May need refresh |
Medium |
lastUpdated mismatch across versions |
Versions out of sync |
Medium |
Git or file mtime newer than translatedDate |
Content changed without frontmatter update |
Warning |
When available, store and compare sourceHash, source dateModified,
translationHash, and Git mtime before relying only on translatedDate.
Emit actionable commands per stale file:
3 translations are stale:
- de/ki-trends-2026.md (source updated 2 days ago)
-> Run: /blog translate en/ai-trends-2026.md --to de
- fr/ki-trends-2026.md (source updated 2 days ago)
-> Run: /blog translate en/ai-trends-2026.md --to fr
- es/tendencias-ia-2026.md (translation > 90 days old)
-> Run: /blog translate en/ai-trends-2026.md --to es
Phase 7: Report
Output as markdown by default. If the user passes --html, also write the
report to locale-audit-report.html only inside the audited project root.
Escape all dynamic filenames, titles, URLs, and issue text with
html.escape(value, quote=True) before rendering HTML, and reject symlinked
or outside-root report paths.
## Multilingual content audit report
### Summary
- Posts audited: [N] across [N] languages
- Overall health: [score] / 100
- Critical issues: [N]
- Warnings: [N]
### Translation coverage
[Matrix from Phase 2]
### Issues found
#### Critical
- [Issue with file references]
#### Warnings
- [Issue with file references]
#### Passed
- [Checks that passed]
### Prioritized fixes
1. [Highest-impact action]
2. [...]
### Stale-translation alerts
[Runnable commands from Phase 6]
### Quick fixes
- Run `/blog translate <file> --to <missing-langs>` for [N] missing translations.
- Run `/blog multilingual` to regenerate hreflang assets.
- Run `/blog localize <file> --locale <code>` for weak cultural adaptations.
Error Handling
| Scenario |
Action |
| Empty directory |
"No blog posts found in [path]" |
| Only one language present |
Report coverage, suggest target languages |
| No hreflang files |
Flag as critical gap, offer regeneration |
| Unrecognized file format |
Skip with a warning |
Cross-References
- Fill missing translations:
/blog translate <file> --to <missing-codes>
- Deepen weak adaptations:
/blog localize <file> --locale <code>
- Regenerate hreflang assets:
/blog multilingual <topic> --languages <codes>