hainrixz/claude-seo-ai

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.

First seen Jun 2, 2026

Installation

$ npx skills add hainrixz/claude-seo-ai --skill seo-local

Summary

  • 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.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from hainrixz/claude-seo-ai · top by installs.

npx skills add hainrixz/claude-seo-ai

Browse all from hainrixz/claude-seo-ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 57
License LICENSE
Default branch main
Open issues 0
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Grep, Glob, WebFetch, Bash

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,335 B
  • docs SUMMARY.md 365 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 144 installs

SKILL.md

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).

Inputs

Work from the PageSnapshot named in your dispatch envelope: read parsed from <rundir>/pages/<slug>.json (jsonld[], textsample, iframes for maps) and vertical from the envelope; Grep pages/<slug>.html for verbatim evidence; site artifacts live in <rundir>/site/{robots.json,sitemaps.json,discovery.json}. Deterministic findings already emitted by audit.mjs are listed in <rundir>/findings.deterministic.json — do not re-emit those ids; add model-judged findings only. If invoked directly with a URL/path and no snapshot exists, first run node "${CLAUDEPLUGINROOT}/scripts/snapshot.mjs" <target> --out "${CLAUDEPLUGINDATA}/runs" and use the printed snapshot path.

Audits

Working from the PageSnapshot (parsed_rendered when render.used is not none, else parsed), 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 "${CLAUDEPLUGINROOT}/scripts/validate-jsonld.mjs" --snapshot <pages/<slug>.json> (or --url <u>) (schemavalidator) — JSON validity + required LocalBusiness props; domassert 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. Severity policy: 5 is reserved for catastrophic, eligibility-killing facts at site/template scope; 4 major · 3 moderate · 2 minor · 1 cosmetic · 0 informational — and only an established severity-5 fail in an active category can cap a score (references/scoring-model.md). 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.