/seo-local
Audit and generate Local SEO signals for local-business pages — verify LocalBusiness JSON-LD, NAP consistency, geo coordinates, openingHoursSpecification, and service-area, advise on Google Business Profile alignment, and produce ready-to-inject LocalBusiness JSON-LD. Module M19
$ npx -y skills add Hainrixz/claude-seo-ai --skill seo-local --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/seo-local
Context preview
The summary Claude sees to decide when to auto-load this skill.
Audit and generate Local SEO signals for local-business pages — verify LocalBusiness JSON-LD, NAP consistency, geo coordinates, openingHoursSpecification, and service-area, advise on Google Business Profile alignment, and produce ready-to-inject LocalBusiness JSON-LD. Module M19
SKILL.md
seo-local.SKILL.mdname: seo-local
description: Audit and generate Local SEO signals for local-business pages — verify LocalBusiness JSON-LD, NAP consistency, geo coordinates, openingHoursSpecification, and service-area, advise on Google Business Profile alignment, and produce ready-to-inject LocalBusiness JSON-LD. Module M19 (conditional). Feeds both the Search SEO and AI Visibility scores.
allowed-tools: Read, Grep, Glob, WebFetch, Bash
seo-local (M19)
Local pages live and die on consistent, machine-readable place data. **Conditional module**: only runs when the page is classified local-business (storefront, service-area, multi-location, contact/location page). Reference: `references/schema-tier1.md` (LocalBusiness row).
Audits
Working from the PageSnapshot (`rendered_dom` if present, else `raw_html`), only for local-business pages: 1. **LocalBusiness schema**: a `LocalBusiness` (or correct subtype, e.g. `Restaurant`, `Dentist`) JSON-LD block with required props — `name`, `address` (`PostalAddress`), `telephone`. 2. **NAP consistency**: visible Name / Address / Phone match across the page (header, footer, contact block) and match the schema values — no formatting drift, no stale numbers. 3. **Geo coordinates**: `geo` (`GeoCoordinates` with `latitude`/`longitude`) present and plausible for the stated address. 4. **Opening hours**: `openingHoursSpecification` present, structured (`dayOfWeek`, `opens`, `closes`), and agreeing with any visible hours. 5. **Service-area**: for service-area businesses, `areaServed` declared rather than (or alongside) a `PostalAddress` storefront. 6. **GBP alignment (advisory)**: NAP, categories, and hours should match the Google Business Profile — the tool cannot read GBP, so this is advisory only.
Fixes
- **AUTO**: generate a complete, valid `LocalBusiness` JSON-LD block from **user-confirmed** NAP, hours, geo, and service-area, with a stable `@id`. The block is a diff for `fix`.
- **NAP / hours drift**: PROPOSED — surface the mismatch and a draft correction for per-item accept (the tool cannot know which value is canonical).
- **GBP alignment**: ADVISORY — never written by the tool.
**Never fabricate** an address, phone, coordinates, or hours — ask the user or leave a clearly-marked `TODO` placeholder they fill before injection.
Verification
- Offline: `node ${CLAUDE_SKILL_DIR}/../../scripts/validate-jsonld.mjs --url <u>` (`schema_validator`) — JSON validity + required LocalBusiness props; `dom_assert` confirms visible NAP matches schema.
- Tier 1: confirm rich-result eligibility with Google Rich Results Test / schema.org validator. When the data tier (or GBP) is unavailable, status is `needs_api` — never a false `pass`.
Findings
Emit findings per `schema/finding.schema.json`. On a non-local page these are `not_applicable` (severity 0); on local pages severity is 4, axis `both`. Examples:
- `M19.localbusiness.missing` — local page with no LocalBusiness schema (status `fail`, severity 4, `fixable: auto`, axis `both`, confidence `established`). `evidence.observed` quotes the visible address/phone with no matching `ld+json`; `verification.reproduce` runs the validator above.
- `M19.nap.inconsistent` — footer phone differs from schema `telephone` (status `warn`, severity 4, `fixable: proposed`, axis `both`, confidence `directional`). `evidence.observed` quotes both strings; verified by `dom_assert`.
- `M19.hours.missing` — no `openingHoursSpecification` despite visible hours (status `warn`, severity 4, `fixable: auto`, axis `both`, confidence `established`).
Each finding: `evidence.observed` quotes the page; `expected_impact` is banded + confidence-tagged (no naked %).
Honesty
- Consistent NAP + structured place data are **established** signals for local pack/maps and AI place answers; raw on-page **proximity/ranking gains are not promised** here — the dominant local-pack factors (proximity, GBP signals, reviews) sit outside the page DOM and are advisory.
- Adding `geo`/`openingHoursSpecification` will **not** by itself move local rankings without an accurate, verified GBP; never ship that as a guaranteed win.
- Do not invent coordinates from an address via an unverified geocode and present them as fact — mark unconfirmed values `TODO`.
Read more
name: seo-local description: Audit and generate Local SEO signals for local-business pages — verify LocalBusiness JSON-LD, NAP consistency, geo coordinates, openingHoursSpecification, and service-area, advise on Google Business Profile alignment, and produce ready-to-inject LocalBusiness JSON-LD. Module M19 (conditional). Feeds both the Search SEO and AI Visibility scores. allowed-tools: Read, Grep, Glob, WebFetch, Bash
seo-local (M19)
Local pages live and die on consistent, machine-readable place data. **Conditional module**: only runs when the page is classified local-business (storefront, service-area, multi-location, contact/location page). Reference: `references/schema-tier1.md` (LocalBusiness row).
Audits
Working from the PageSnapshot (`rendered_dom` if present, else `raw_html`), only for local-business pages: 1. **LocalBusiness schema**: a `LocalBusiness` (or correct subtype, e.g. `Restaurant`, `Dentist`) JSON-LD block with required props — `name`, `address` (`PostalAddress`), `telephone`. 2. **NAP consistency**: visible Name / Address / Phone match across the page (header, footer, contact block) and match the schema values — no formatting drift, no stale numbers. 3. **Geo coordinates**: `geo` (`GeoCoordinates` with `latitude`/`longitude`) present and plausible for the stated address. 4. **Opening hours**: `openingHoursSpecification` present, structured (`dayOfWeek`, `opens`, `closes`), and agreeing with any visible hours. 5. **Service-area**: for service-area businesses, `areaServed` declared rather than (or alongside) a `PostalAddress` storefront. 6. **GBP alignment (advisory)**: NAP, categories, and hours should match the Google Business Profile — the tool cannot read GBP, so this is advisory only.
Fixes
- **AUTO**: generate a complete, valid `LocalBusiness` JSON-LD block from **user-confirmed** NAP, hours, geo, and service-area, with a stable `@id`. The block is a diff for `fix`.
- **NAP / hours drift**: PROPOSED — surface the mismatch and a draft correction for per-item accept (the tool cannot know which value is canonical).
- **GBP alignment**: ADVISORY — never written by the tool.
**Never fabricate** an address, phone, coordinates, or hours — ask the user or leave a clearly-marked `TODO` placeholder they fill before injection.
Verification
- Offline: `node ${CLAUDE_SKILL_DIR}/../../scripts/validate-jsonld.mjs --url <u>` (`schema_validator`) — JSON validity + required LocalBusiness props; `dom_assert` confirms visible NAP matches schema.
- Tier 1: confirm rich-result eligibility with Google Rich Results Test / schema.org validator. When the data tier (or GBP) is unavailable, status is `needs_api` — never a false `pass`.
Findings
Emit findings per `schema/finding.schema.json`. On a non-local page these are `not_applicable` (severity 0); on local pages severity is 4, axis `both`. Examples:
- `M19.localbusiness.missing` — local page with no LocalBusiness schema (status `fail`, severity 4, `fixable: auto`, axis `both`, confidence `established`). `evidence.observed` quotes the visible address/phone with no matching `ld+json`; `verification.reproduce` runs the validator above.
- `M19.nap.inconsistent` — footer phone differs from schema `telephone` (status `warn`, severity 4, `fixable: proposed`, axis `both`, confidence `directional`). `evidence.observed` quotes both strings; verified by `dom_assert`.
- `M19.hours.missing` — no `openingHoursSpecification` despite visible hours (status `warn`, severity 4, `fixable: auto`, axis `both`, confidence `established`).
Each finding: `evidence.observed` quotes the page; `expected_impact` is banded + confidence-tagged (no naked %).
Honesty
- Consistent NAP + structured place data are **established** signals for local pack/maps and AI place answers; raw on-page **proximity/ranking gains are not promised** here — the dominant local-pack factors (proximity, GBP signals, reviews) sit outside the page DOM and are advisory.
- Adding `geo`/`openingHoursSpecification` will **not** by itself move local rankings without an accurate, verified GBP; never ship that as a guaranteed win.
- Do not invent coordinates from an address via an unverified geocode and present them as fact — mark unconfirmed values `TODO`.
The SEO + AI-search (GEO/AEO) optimization toolkit for Claude Code — two-score audit + opt-in fixer. Built for 2026-2027.
Repo: Hainrixz/claude-seo-ai
Other skills on claude-seo-ai.
- /audit
Audit a website or web codebase for SEO and AI-search (GEO/AEO) — produces two independent 0-100 scores (Search SEO + AI Visibility) plus a prioritized, evidence-backed report. Read-only; never writes files. Use when the user asks to audit, analyze, check, or score a site's SEO,
Open skill - /fix
Opt-in fixer (the /claude-seo-ai:fix command). Applies the safe, deterministic SEO/AI-search fixes from an audit to the user's code — meta viewport/charset/lang, JSON-LD, robots.txt AI directives, hreflang, sitemaps, OG/Twitter cards, image dimensions, canonical, llms.txt.
Open skill - /geo
Analyze and score only a page's AI-search visibility (GEO/AEO) — answer extractability, fact density, AI-crawler access, entity linking, and llms.txt — and report an AI Visibility score with a citability breakdown. Read-only. Use for "will AI engines cite this?", GEO/AEO, or
Open skill - /score
Recompute and display the two scores (Search SEO + AI Visibility) from the most recent audit's findings, without re-crawling. Use to re-show or refresh the scores after an audit, or to score a saved findings JSON file.
Open skill - /seo-ai-crawlers
Audit AI crawler access and citability for a page — confirm retrieval/citation bots (OAI-SearchBot, Claude-SearchBot, PerplexityBot) are allowed and the Googlebot vs Google-Extended split is correct, classify training vs search/retrieval vs user-fetch user-agents, check the page
Open skill - /seo-core-web-vitals
Audit Core Web Vitals & page performance — measure LCP, INP, and CLS against p75 field thresholds, diagnose render-blocking resources, unoptimized images, and layout-shift sources, and produce prioritized, advisory-only remediation guidance. Module M15. Feeds the Search SEO
Open skill

