geo-fix-schema ยท diff
v1.0.0 to v1.1.0
26 added, 1 removed. Audit B to B.
---
name: geo-fix-schema
description: Analyze a website's structured data and generate ready-to-use JSON-LD schema markup to improve AI discoverability. Use when the user asks to fix schema, add structured data, generate JSON-LD, add schema markup, or improve schema.org markup for AI engines.
- version: 1.0.0
+ version: 1.1.0
---
# geo-fix-schema Skill
You analyze a website's existing structured data and generate ready-to-use JSON-LD schema markup that improves AI discoverability and citation likelihood. The output is copy-paste-ready code that the user can inject into their site's `<head>`.
Refer to `references/schema-templates.md` in this skill's directory for JSON-LD template patterns.
+ ### GEO Score Impact
+
+ In the geo-audit scoring model (v2), Structured Data is one of the 4 core dimensions with a **20% weight** in the composite GEO Score. The dimension scores up to 100 points across 4 sub-dimensions:
+
+ | Sub-dimension | Max Points | Key Schemas |
+ |---------------|-----------|-------------|
+ | Core Identity Schema | 30 | Organization/LocalBusiness, sameAs, WebSite |
+ | Content Schema | 25 | Article/BlogPosting, Author, datePublished, Speakable |
+ | AI-Boost Schema | 25 | FAQPage, HowTo, BreadcrumbList, Business-specific |
+ | Schema Quality | 20 | JSON-LD format, syntax validity, required properties |
+
+ A site with no structured data scores 0/100 on this dimension, losing up to **20 points** from the composite GEO Score. Implementing the core schemas (Organization + WebSite + one content type) typically recovers 40-60 points in this dimension.
+
---
## Phase 1: Discovery
### 1.1 Validate Input
Extract the target URL from the user's input. Normalize it:
- Add `https://` if no protocol specified
- Remove trailing slashes
- Extract the base domain
### 1.2 Fetch and Analyze Pages
Fetch the homepage and up to 5 additional key pages (about, blog post, product page, FAQ, contact).
For each page, extract:
- All `<script type="application/ld+json">` blocks
- Microdata attributes (`itemscope`, `itemtype`, `itemprop`)
- RDFa attributes (`typeof`, `property`)
- `<meta>` tags (og:*, twitter:*, description, author)
- Page content structure (headings, lists, Q&A patterns)
### 1.3 Detect Business Type
Classify the site based on content signals:
| Type | Signals |
|------|---------|
| **SaaS** | Sign up, pricing, API, dashboard, integrations |
| **E-commerce** | Cart, buy, product listings, prices, SKUs |
| **Publisher** | Articles, bylines, dates, categories |
| **Local Business** | Address, phone, hours, map, service area |
| **Agency** | Services, case studies, portfolio, client logos |
---
## Phase 2: Schema Audit
### 2.1 Inventory Existing Schema
Build a table of what exists:
```
Schema Audit: {domain}
| Schema Type | Found | Format | Valid | Issues |
|-------------|-------|--------|-------|--------|
| Organization | Yes/No | JSON-LD/Microdata/None | Yes/No | ... |
| WebSite | Yes/No | ... | ... | ... |
| Article | Yes/No | ... | ... | ... |
| ...
```
### 2.2 Score Current State
Use the scoring rubric from the geo-audit schema dimension:
| Check | Max Points | Current |
|-------|-----------|---------|
| Core Identity Schema | 30 | {x}/30 |
| Content Schema | 25 | {x}/25 |
| AI-Boost Schema | 25 | {x}/25 |
| Schema Quality | 20 | {x}/20 |
| **Total** | **100** | **{x}/100** |
### 2.3 Identify Gaps
For each missing or incomplete schema, document:
- What's missing
- Why it matters for AI visibility
- Point impact (how much the score would improve)
- Priority (Critical / High / Medium / Low)
---
## Phase 3: Generate JSON-LD
Generate ready-to-use JSON-LD for each gap, ordered by priority.
### 3.1 Core Identity (always generate if missing)
**Organization / LocalBusiness:**
Extract from the site:
- Name (from title, og:site_name, footer, about page)
- Description (from meta description, about page)
- Logo URL (from og:image, header logo, favicon)
- URL (canonical domain)
- Social profiles (from footer links, og:see_also)
- Contact info (from contact page, footer)
Generate:
```json
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "{extracted name}",
"url": "{url}",
"logo": "{logo_url}",
"description": "{extracted description}",
"sameAs": [
"{linkedin_url}",
"{twitter_url}",
"{github_url}"
],
"contactPoint": {
"@type": "ContactPoint",
"contactType": "customer service",
"url": "{contact_page_url}"
}
}
```
For Local Business, use `@type: "LocalBusiness"` and add:
- `address` (PostalAddress)
- `telephone`
- `openingHoursSpecification`
- `geo` (latitude, longitude)
**WebSite + SearchAction:**
```json
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "{site_name}",
"url": "{url}",
"potentialAction": {
"@type": "SearchAction",
"target": "{url}/search?q={search_term_string}",
"query-input": "required name=search_term_string"
}
}
```
Only include SearchAction if a search function exists on the site.
### 3.2 Content Schema (generate per content page)
**Article / BlogPosting:**
Extract from each article page:
- Headline (H1)
- Author (byline, author meta)
- Date published / modified
- Description (meta description or first paragraph)
- Image (og:image or first content image)
- Word count
```json
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "{h1}",
"author": {
"@type": "Person",
"name": "{author_name}",
"url": "{author_url}"
},
"datePublished": "{iso_date}",
"dateModified": "{iso_date}",
"description": "{meta_description}",
"image": "{image_url}",
"publisher": {
"@type": "Organization",
"name": "{site_name}",
"logo": {
"@type": "ImageObject",
"url": "{logo_url}"
}
},
"mainEntityOfPage": "{canonical_url}",
"wordCount": {word_count},
"speakable": {
"@type": "SpeakableSpecification",
"cssSelector": ["h1", ".article-summary", ".article-body p:first-of-type"]
}
}
```
**Person (Author):**
If author pages exist, generate Person schema with:
- name, url, jobTitle, worksFor, sameAs (social links)
### 3.3 AI-Boost Schema (generate when content patterns match)
**FAQPage:**
Detect Q&A patterns in page content:
- `<h2>` or `<h3>` phrased as questions
- Sections with "Q:" / "A:" patterns
- Accordion/expandable FAQ elements
```json
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "{question_text}",
"acceptedAnswer": {
"@type": "Answer",
"text": "{answer_text}"
}
}
]
}
```
**HowTo:**
Detect step-by-step content:
- Numbered lists
- "Step 1", "Step 2" headings
- Tutorial/guide content
```json
{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "{title}",
"description": "{description}",
"step": [
{
"@type": "HowToStep",
"name": "{step_title}",
"text": "{step_description}"
}
]
}
```
**BreadcrumbList:**
Generate from URL structure and navigation:
```json
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "{url}"
},
{
"@type": "ListItem",
"position": 2,
"name": "{section}",
"item": "{section_url}"
}
]
}
```
**Product (E-commerce only):**
```json
{
"@context": "https://schema.org",
"@type": "Product",
"name": "{product_name}",
"description": "{description}",
"image": "{image_url}",
"brand": {
"@type": "Brand",
"name": "{brand}"
},
"offers": {
"@type": "Offer",
"price": "{price}",
"priceCurrency": "{currency}",
"availability": "https://schema.org/InStock",
"url": "{product_url}"
}
}
```
---
## Phase 4: Output
### 4.1 Generate Installation File
Create a file named `schema-{domain}.json` containing all generated JSON-LD blocks, each wrapped in a `<script>` tag and annotated with comments indicating which page it belongs to:
```html
<!-- ============================================ -->
<!-- HOMEPAGE: Organization + WebSite -->
<!-- Place in <head> of: {url} -->
<!-- ============================================ -->
<script type="application/ld+json">
{...Organization JSON-LD...}
</script>
<script type="application/ld+json">
{...WebSite JSON-LD...}
</script>
<!-- ============================================ -->
<!-- BLOG POST: Article -->
<!-- Place in <head> of: {blog_post_url} -->
<!-- ============================================ -->
<script type="application/ld+json">
{...Article JSON-LD...}
</script>
```
### 4.2 Print Summary
```
Schema Fix: {domain}
Current score: {x}/100
After fixes: {y}/100 (estimated +{delta} points)
Generated {n} JSON-LD blocks:
| Schema | Page | Impact | Why It Matters |
|--------|------|--------|----------------|
| Organization | Homepage | +12 pts | AI uses this to identify your brand and link to knowledge graphs |
| WebSite | Homepage | +5 pts | Enables sitelinks search box in AI-generated answers |
| Article | /blog/post-1 | +8 pts | Helps AI understand authorship, freshness, and content authority |
| FAQPage | /faq | +8 pts | Directly feeds AI Q&A engines, increases citation probability |
| BreadcrumbList | All pages | +5 pts | Provides hierarchical context for AI content understanding |
Output file: schema-{domain}.json
Installation:
1. Copy the relevant <script> blocks into each page's <head>
2. Validate at https://validator.schema.org/
3. Test at https://search.google.com/test/rich-results
```
---
## Quality Gates
1. **Valid JSON**: All generated JSON-LD must be syntactically valid
2. **Required properties**: Every schema must include all required properties per schema.org spec
3. **Real data only**: Never invent data โ if a field cannot be extracted, omit it or mark as `TODO`
4. **No duplicate schemas**: If a schema type already exists on a page, suggest improvements instead of adding duplicates
5. **URL validation**: All URLs in schema must be absolute and verified accessible
6. **Rate limiting**: 1 second between requests to the same domain
7. **Respect robots.txt**: Do not fetch pages blocked by robots.txt
+
+ ---
+
+ ## Error Handling
+
+ - **URL unreachable**: Report the error and stop โ schema analysis requires page access
+ - **No existing schema found**: This is expected for many sites โ proceed directly to generation (Phase 3)
+ - **Invalid existing JSON-LD**: Report syntax errors with line-level detail, then generate corrected versions
+ - **robots.txt blocks us**: Note the restriction, only analyze accessible pages
+ - **Rate limiting**: Wait 1 second between requests to the same domain
+ - **Timeout**: 30 seconds per URL fetch
+ - **Cannot extract required fields**: Use `TODO` placeholders and clearly mark them in the output; never invent data
---
## Business Type Priority
Different business types need different schemas first:
| Business Type | Priority Schemas |
|---------------|-----------------|
| **SaaS** | Organization, WebSite, FAQPage, HowTo, Article |
| **E-commerce** | Organization, Product, BreadcrumbList, FAQPage, WebSite |
| **Publisher** | Organization, Article, Person, BreadcrumbList, WebSite |
| **Local** | LocalBusiness, FAQPage, BreadcrumbList, WebSite |
| **Agency** | Organization, Person, FAQPage, Article, WebSite |