Help us improve
Share bugs, ideas, or general feedback.
From seo-skills
Audits local SEO signals for brick-and-mortar, service-area, and multi-location businesses: GBP integration, NAP consistency, local-pack rank, citations, and reviews.
npx claudepluginhub seranking/seo-skills --plugin seo-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/seo-skills:seo-localThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Example output: [examples/seo-local-sweetgreen-com-20260514/LOCAL-SEO-REPORT.md](../../examples/seo-local-sweetgreen-com-20260514/LOCAL-SEO-REPORT.md)
Audits local SEO health including GBP completeness, NAP consistency, citation presence, local content, reviews, and schema, producing a prioritized action plan.
Performs local SEO analysis on websites: GBP optimization, NAP consistency, citation health, review signals, schema markup, location pages, multi-location SEO. Detects business type and industry vertical.
Audits business local search presence including GBP completeness, categories, photos, citations, reviews, website signals, and links. Delivers prioritized actionable recommendations on audit triggers like 'local SEO audit' or ranking issues.
Share bugs, ideas, or general feedback.
Example output: examples/seo-local-sweetgreen-com-20260514/LOCAL-SEO-REPORT.md
Score a local business's website against the signals that drive local-pack and "near me" visibility — GBP integration on the page, NAP consistency, on-page local intent, citation footprint on Tier-1 directories, review-platform presence, and local-pack rank for the business's primary keywords. Deliverable is one prioritised fix list, anchored in observable signals.
Adapted from
AgriciDaniel/claude-seo'sseo-localskill (MIT). Concept and dimension structure mirror the upstream; backend rewired to SE Ranking + Firecrawl + Google APIs. DataForSEO Maps geo-grid and Business Listings checks from the upstream are dropped (no equivalent backend) — see "Limitations" in the deliverable.
WebFetch tool available (used for sense-check fallback when Firecrawl is unavailable)."dentist Brooklyn", "plumber near me"), (c) target country and ideally city/region for local-pack scoping. Optional: GBP listing URL, Yelp/Trustpilot URLs for review scraping.Validate target & preflight. See skills/seo-firecrawl/references/preflight.md for the canonical 3-stage preflight (credit balance, Firecrawl availability, Google APIs). Skill-specific notes:
<title> + <h1> of the homepage; if still ambiguous, ask the user before continuing.tel: / address element extraction become best-effort prose inspection. Pass --no-firecrawl to force WebFetch-only.skills/seo-google/references/cross-skill-integration.md for the full enrichment contract.Business-type detection
/contact + footer prose (WebFetch markdown is enough for this).areaServed in schema without address.streetAddress.LOCAL-SEO-REPORT.md "Snapshot".Industry-vertical detection
/menu, /practice-areas, /listings, /inventory), <title>, page prose, infer one of: Restaurant / Healthcare / Legal / Home Services / Real Estate / Automotive / Generic.references/local-citation-sources.md for the vertical's Tier-1 directories.GBP signals on the page mcp__firecrawl-mcp__firecrawl_scrape (with formats: ["rawHtml"])
/contact (or whichever page has the most local intent).rawHtml extract:
<iframe src="https://www.google.com/maps/embed?...">) — record place ID if present.aggregateRating JSON-LD block (presence is the strongest signal that the site wants stars in SERPs).<a href="tel:..."> elements.<a href> to https://g.page/... or https://maps.app.goo.gl/... or https://www.google.com/maps/place/....tel: link in some renderings but loses iframes and JSON-LD. Mark Maps embed / aggregateRating / GBP profile-link detection as (skipped — Firecrawl required).NAP consistency mcp__firecrawl-mcp__firecrawl_scrape on homepage + 5 sample pages
/contact, /about, plus 2 service or location pages (pick from sitemap or top traffic pages).tel: href + display format), business name (logo alt, footer, schema name).<script type="application/ld+json"> block. Pull name, address.streetAddress, address.addressLocality, address.addressRegion, address.postalCode, telephone.nap-inconsistencies.csv.nap-inconsistencies.csv is empty after the scan, write nap-inconsistencies.csv as a one-line file with header only and note "NAP consistent across {n} pages and schema" in LOCAL-SEO-REPORT.md.Local-pack rank tracking DATA_getSerpResults with country/region filters
DATA_getSerpResults with the user's country and the most specific region/city the API supports (use DATA_getSerpLocations first to confirm a valid location code if the user supplied a city).local-keywords.csv (columns: keyword,country,location,local_pack_present,target_in_pack,target_pack_position,target_organic_position,top_pack_competitor_1,top_pack_competitor_2,top_pack_competitor_3).Reviews scraping mcp__firecrawl-mcp__firecrawl_scrape on user-provided review URLs
https://www.google.com/maps/place/...), Yelp business URL, Trustpilot business URL, BBB profile URL.formats: ["rawHtml"]. From the parsed DOM, extract: total review count, average rating, date of most recent review (review velocity proxy), count of owner responses on the most recent 10 reviews.LOCAL-SEO-REPORT.md: "Review platforms: not provided. To audit review health, re-run with --reviews 'gbp_url,yelp_url,trustpilot_url'." Don't try to discover them — review-URL discovery is a different problem (and the Maps API path is the one we don't have).On-page local-SEO audit DATA_getAuditReport (existing audit) + DATA_getIssuesByUrl on the homepage
seo-technical-audit). Don't create a new audit just for local — the audit data already covers title-tag issues, missing schema, mobile usability, etc.LocalBusiness JSON-LD.aggregateRating, malformed address).seo-schema. This skill does NOT generate JSON-LD. If LocalBusiness schema is missing or broken, the deliverable says "Run seo-schema for paste-ready LocalBusiness markup with the correct industry subtype" — that's seo-schema's job and reimplementing it here would duplicate work.8b. GSC local query performance (only if google-api.json is present, tier ≥ 1)
python3 scripts/gsc_query.py --property "{config.default_property}" --days 28 --jsonnear me, contains a city/region known for the business, or ends in a place-name. Surface top 10 by impressions.LOCAL-SEO-REPORT.md "Top fixes" with the GSC numbers as supporting evidence.skills/seo-google/references/cross-skill-integration.md for failure modes.8c. GA4 organic by landing page (only if google-api.json is present, tier ≥ 2)
python3 scripts/ga4_report.py --report top-pages --days 28 --jsonCitation-presence sample (best-effort) WebSearch (no API key cost)
references/local-citation-sources.md), check whether the business has a listing using site:{directory} "{business_name}" queries via WebSearch.LOCAL-SEO-REPORT.md "Citations" section: detected / not detected per directory, plus the URL of the listing if found.Synthesise LOCAL-SEO-REPORT.md
Create a folder seo-local-{domain-slug}-{YYYYMMDD}/ with:
seo-local-{domain-slug}-{YYYYMMDD}/
├── LOCAL-SEO-REPORT.md (PRIMARY: verdict, scores, top fixes, limitations)
├── local-keywords.csv (load-bearing: per-keyword local-pack + organic positions)
├── nap-inconsistencies.csv (load-bearing: only emitted if discrepancies found)
└── evidence/
├── 01-homepage-snapshot.md (Firecrawl raw HTML extracts: NAP, schema, GBP signals)
├── 02-nap-page-samples.md (per-page NAP extracts across 5 sample URLs)
├── 03-serp-context.md (raw DATA_getSerpResults per keyword)
├── 04-reviews.md (per-platform review-page snapshots, only if user provided URLs)
└── 05-citation-sample.md (raw WebSearch results per directory check)
LOCAL-SEO-REPORT.md follows this shape:
# Local SEO Report: {domain}
> Snapshot dated {YYYY-MM-DD} · Country: {country} · Region: {region} · Primary keyword: "{keyword}"
## Snapshot
- Business type: {Brick-and-Mortar | SAB | Hybrid}
- Industry vertical: {Restaurant | Healthcare | Legal | Home Services | Real Estate | Automotive | Generic}
- Pages sampled for NAP: {n}
- Local keywords tracked: {n}
- Local pack present on {n}/{m} keywords; target in pack on {p}/{m}
- Review platforms audited: {Google, Yelp, ... | not provided}
- GSC last 28d local-intent queries: {n} queries / {clicks} clicks / {impressions} impressions *(or `not configured`)*
## Verdict: {STRONG | NEEDS WORK | WEAK}
{One-sentence summary anchored in dimension scores below}
## Dimension scores (0–10)
| Dimension | Score | Top finding |
|---|---|---|
| GBP integration on page | {n}/10 | {one-line} |
| NAP consistency | {n}/10 | {one-line} |
| Local on-page (title/H1/contact/service pages) | {n}/10 | {one-line} |
| Local-pack rank | {n}/10 | {one-line} |
| Reviews & citations | {n}/10 | {one-line} |
| **Composite** | {n}/10 | — |
## Top fixes
### Critical
1. {Specific fix anchored in a finding above. Example: "NAP discrepancy: footer shows '(212) 555-1234' but JSON-LD shows '+1-212-555-9999'. Pick one canonical phone, fix the wrong one." Cite the page/schema source.}
### High
- {fix}
### Medium
- {fix}
### Low
- {fix}
## Local-pack rank summary
- "{keyword 1}": local pack {present/absent}, target {in pack at #n / not in pack}, organic position {n}.
- "{keyword 2}": …
- (Full data: `local-keywords.csv`)
## Reviews health (if audited)
- Google: {n} reviews, {rating} avg, last review {n} days ago, owner response rate {p}%.
- Yelp: …
- Trustpilot: …
## Citation sample
- Google Business: {detected / not detected via site:google.com "..." search}
- Yelp: …
- Facebook: …
- BBB: …
- Apple Business Connect: …
- Bing Places: …
- {vertical-specific 1}: …
- {vertical-specific 2}: …
(Caveat: this is a sample, not a comprehensive citation audit. For definitive coverage, use Whitespark / BrightLocal / Yext.)
## Schema status
- LocalBusiness JSON-LD: {present and valid / present but missing recommended properties / invalid / absent}
- Recommended next step: run `seo-schema {homepage_url}` for paste-ready LocalBusiness markup with the correct industry subtype.
## Limitations
This skill could NOT assess:
- **Geo-grid local-pack rank by lat/long.** Requires a Maps API (e.g. DataForSEO Maps geo-grid endpoint) we don't have. Workaround: pay for Local Falcon, GMB Crush, or BrightLocal Local Search Grid.
- **Comprehensive citation audit.** WebSearch sampling covers ~8 directories; full audits cover 50+. Use Whitespark, BrightLocal, or Yext.
- **GBP Insights data.** Requires GBP API access scoped to the listing owner. Ask the listing owner to export Insights and share.
- **Real-time local-pack rank tracking over time.** This skill is a snapshot. Use SE Ranking's project-level rank tracker (`PROJECT_runPositionCheck`) or pair with `seo-drift` for diff snapshots.
- **DataForSEO Business Listings.** Not in our backend; if the user needs it, they'd need to subscribe to DataForSEO directly.
local-keywords.csv columns: keyword,country,location,local_pack_present,target_in_pack,target_pack_position,target_organic_position,top_pack_competitor_1,top_pack_competitor_2,top_pack_competitor_3,aio_present
nap-inconsistencies.csv columns: source,name,address,phone,page_or_schema_path,canonical_value,divergence_note
DATA_getSerpResults calls sequentially.DATA_getCreditBalance before running. ~15–25 SE Ranking credits typical, plus 6–12 Firecrawl credits when Firecrawl is installed.seo-schema for that — it has the rich-results validation and industry-subtype routing this skill doesn't replicate.seo-content-audit on a sample of location pages.seo-geo (URL-level GEO) or seo-ai-search-share-of-voice (domain-level brand visibility) for AI-search local visibility.references/local-citation-sources.md. The list is curated to the directories that move the needle (Tier 1 + vertical-specific), not the long tail.seo-technical-audit if site-wide technical-SEO issues surface in step 8 — this skill scopes to local-relevant findings, not the full audit.