seranking/seo-hreflang
Hreflang and international SEO audit for multi-language and multi-region sites. Validates language-region codes, return tags, x-default, canonical alignment, and conflict detection across the per-URL HTML, the SE Ranking audit, and the XML sitemap. Use when the user asks "hreflang", "international SEO", "i18n", "language targeting", "x-default", "regional sites", or "multi-language SEO".
npx skills add https://github.com/seranking/seo-skills --skill seo-hreflang
> Example output: examples/seo-hreflang-airbnb-com-20260514/HREFLANG-REPORT.md
Adapted from AgriciDaniel/claude-seo's seo-hreflang skill (MIT). Concept and validation rules originate there; this implementation is rebuilt against our backend (SE Ranking MCP + Firecrawl + WebFetch + Google APIs via seo-google).
Validate hreflang implementations on a multi-language or multi-region site. Surface SE Ranking audit-level hreflang issues, parse a sample of pages for the actual <link rel="alternate" hreflang="…"> tags they emit, cross-check the sitemap, and produce one of three verdicts — PASS, NEEDS-FIX, or BROKEN — with a top-fixes table anchored in objective signals.
WebFetch tool available (fallback when Firecrawl is unavailable).example.com). Optional: explicit list of representative pages to inventory; explicit sitemap URL if not at /sitemap.xml.seo-technical-audit or seo-sitemap already run on this domain. Without an existing audit, the skill creates one (which costs significantly more credits).skills/seo-firecrawl/references/preflight.md for the canonical 3-stage preflight (credit balance, Firecrawl availability, Google APIs). Skill-specific notes:formats: ["rawHtml"]. Without Firecrawl, step 4 falls back to WebFetch — coverage is degraded because WebFetch returns markdown only and silently strips <link rel="alternate"> tags from <head>. Pass --no-firecrawl to force WebFetch even when Firecrawl is available.skills/seo-google/references/cross-skill-integration.md for the full enrichment contract.DATA_listAudits → DATA_getAuditStatusDATA_recheckAudit and wait for done.DATA_createStandardAudit — it consumes credits.DATA_getAuditReport + DATA_getAuditPagesByIssueDATA_getAuditReport, extract every issue with code or category matching hreflang (typical codes: hreflang_no_return_tag, hreflang_invalid_lang_code, hreflang_conflict, hreflang_missing_x_default, hreflang_canonical_mismatch, hreflang_no_self_reference).DATA_getAuditPagesByIssue to enumerate the affected URLs.01-audit-hreflang-issues.md and feed into hreflang-issues.csv.mcp__firecrawl-mcp__firecrawl_scrape (preferred) / WebFetch (fallback)DATA_getDomainPages (sort by traffic descending; bias toward pages on different language paths if the URL structure exposes them — /en/, /fr/, /de/, etc.).firecrawl_scrape(url=..., formats=["rawHtml"]). Pin rawHtml — the default html post-processing strips <link rel="alternate"> on many sites. Parse every <link rel="alternate" hreflang="…" href="…"> from the <head>. Capture: source URL, hreflang attribute, href, and whether it's self-referencing.<head> link tags, so this path will under-report. Note in HREFLANG-REPORT.md: Per-URL inventory: degraded coverage — Firecrawl not installed; some hreflang tags may be missed.fr, page B must list A as en (or whichever).hreflang="x-default".- and an ISO 3166-1 Alpha-2 region). Common errors caught: eng (use en), jp (use ja), en-uk (use en-GB), es-LA (no such ISO region).de-DE) appearing on multiple distinct URLs is a conflict — Google ignores conflicting sets.<link rel="canonical">, it must match the page's own URL (or its self-referencing hreflang URL). Hreflang on a non-canonical page is silently ignored by Google.02-per-url-hreflang.md and append findings to hreflang-issues.csv.seo-sitemap where appropriate)<xhtml:link rel="alternate" …> inside the sitemap), this skill checks structure and consistency only. Full sitemap analysis (orphans, missing pages, broken entries) is seo-sitemap's job — recommend it explicitly if a sitemap-vs-audit diff is in scope.https://{domain}/sitemap.xml; if 404, fetch /robots.txt and find Sitemap: directives. For sitemap-of-sitemaps, recursively fetch each child.xmlns:xhtml="http://www.w3.org/1999/xhtml" namespace? Required for hreflang in sitemaps.<url> entry that has hreflang alternates include itself in the alternate set (self-reference)?<url> entry reciprocate as its own <url> entry with the same alternate set (return tags)?03-sitemap-hreflang.md and append findings to hreflang-issues.csv.href target in the hreflang sets (e.g. example.com, example.de, example.fr), confirm GSC verification:python3 scripts/gsc_query.py --property "{property}" --json (a status-only check; just confirm the property responds without PROPERTY_NOT_VERIFIED).
example.de is listed as an alternate but isn't verified in this account, the hreflang signal is weakened and you can't see how Google interprets it.HREFLANG-REPORT.md as a section "## GSC verification of hreflang targets" with one row per target domain: verified / not verified / not configured.skills/seo-google/references/cross-skill-integration.md § "Trigger pattern" for the failure-mode contract.hreflang-issues.csv by severity descending, then count descending.HREFLANG-REPORT.md with the top-fixes table (top 10) and the verdict.Create a folder seo-hreflang-{target-slug}-{YYYYMMDD}/ with:
seo-hreflang-{target-slug}-{YYYYMMDD}/
├── 01-audit-hreflang-issues.md (SE Ranking audit findings filtered to hreflang)
├── 02-per-url-hreflang.md (per-URL <link rel="alternate"> inventory + validation findings)
├── 03-sitemap-hreflang.md (sitemap-level hreflang validation; defer details to seo-sitemap)
├── evidence/
│ ├── homepage-rawhtml.html (raw HTML from Firecrawl, for the homepage sample)
│ ├── sample-{n}-rawhtml.html (raw HTML for each sampled URL)
│ └── sitemap.xml (raw fetched sitemap)
├── hreflang-issues.csv (load-bearing: URL, issue code, severity, fix)
└── HREFLANG-REPORT.md (PRIMARY: verdict + top fixes table)
HREFLANG-REPORT.md follows this shape:
# Hreflang Audit: {domain}
> Audit date {YYYY-MM-DD} · Sample size: {n} URLs · Languages detected: {comma-separated list}
## Verdict: {PASS | NEEDS-FIX | BROKEN}
Reasoning: {1–2 sentences anchored in concrete numbers from the data}.
## Summary
| Source | Findings | Severity breakdown |
|---|---|---|
| SE Ranking audit | {n} | Critical: {n} · High: {n} · Medium: {n} · Low: {n} |
| Per-URL HTML inventory | {n} | … |
| Sitemap | {n} | … |
## Top fixes (impact-ranked)
| # | URL | Issue | Severity | Fix |
|---|---|---|---|---|
| 1 | {URL} | {issue code} | {severity} | {one-line fix} |
| 2 | … | … | … | … |
| ... up to 10 |
## Languages detected
| Language | URL count | Self-ref OK | Return tags OK | x-default OK |
|---|---|---|---|---|
| en-US | {n} | ✓ / ✗ {count} | ✓ / ✗ | ✓ / ✗ |
| de-DE | {n} | … | … | … |
| ... |
## Per-URL inventory ({n} URLs sampled)
| URL | Alternates | Self-ref | x-default | Notable issues |
|---|---|---|---|---|
| {URL} | {n} | ✓/✗ | ✓/✗ | {short text} |
| ... |
## Sitemap-level hreflang
- xhtml namespace declared: {✓/✗}
- URLs with hreflang alternates: {n}
- Self-reference within sitemap: {✓ all / ✗ {count} missing}
- Return tags within sitemap: {✓ all / ✗ {count} missing}
- Per-URL HTML vs sitemap consistency: {✓ all match / ✗ {count} mismatched}
- Full sitemap-vs-audit analysis: see `seo-sitemap` (orphans, broken entries, lastmod).
## GSC verification of hreflang targets
| Domain | Verified | Notes |
|---|---|---|
| {domain1} | ✓ / ✗ | {note if unverified} |
| ... |
(Or: `GSC verification: not configured (run bash extensions/google/install.sh)`.)
## Coverage notes
- Per-URL inventory tool: {Firecrawl rawHtml | WebFetch fallback (degraded — some hreflang tags may be missed)}.
- Pages sampled: homepage + {n} representative pages (selection: top traffic from `DATA_getDomainPages`).
## Apply
- Walk `hreflang-issues.csv` row-by-row; each row is one specific change (URL + issue + fix).
- After applying changes, re-run `seo-technical-audit` to refresh SE Ranking's findings, then re-run this skill to verify.
hreflang-issues.csv columns: url,issue_code,severity,fix,source where source is one of audit | html | sitemap | gsc.
HREFLANG-REPORT.md to a row in hreflang-issues.csv. If a stakeholder questions the verdict, walk them through the CSV.<head> — recommend the sitemap-based implementation instead. Don't generate code; the deliverable is diagnostic, not code-gen.example.com ↔ example.de), step 6's GSC check is the highest-value enrichment — verifying both domains is Google's explicit recommendation.seo-sitemap for the sitemap-vs-audit diff; pair with seo-technical-audit for full technical health. This skill is narrow: hreflang correctness only.references/validation-rules.md for the full per-issue rule table (severity, detection logic, suggested fix).Take seranking/seo-hreflang from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.