Building in Public#building-in-public

Building Schema Markup Without Fake Data

By Mohamed Abdi Guled

Schema markup is a factual claim to a search engine — ShabelleHub had to rebuild its structured data around what was actually true.

Building Schema Markup Without Fake Data

Schema markup is one of those SEO topics where the advice is clear and the temptation to cut corners is high. The advice: add structured data that accurately describes your content. The temptation: add the most impressive-looking schema possible, regardless of whether it matches reality.

ShabelleHub shipped with the second approach. This article covers what we got wrong, what the actual consequences are, and what honest schema markup looks like for a review and directory site.


What We Had

Every tool page emitted AggregateRating structured data:

{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "Claude",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": 4.9,
    "reviewCount": 2840,
    "bestRating": 5,
    "worstRating": 1
  }
}

The reviewCount of 2,840 was invented. ShabelleHub has no user review system. No one submitted 2,840 reviews. The number existed because someone added a reviews field to the tool data during development to make the schema look more authoritative.

The FAQ page had no schema at all.

The blog posts had BlogPosting schema with an author field pointing to a generic "Shabelle Hub Team" entity with no further identification.


The Three Schema Problems

Problem 1: Fabricated AggregateRating

AggregateRating implies that multiple users have rated a product and the schema represents a computed aggregate of those ratings. Using it without a real user rating system is a misrepresentation of what the site provides.

Google's rich results policies state that review markup must represent genuine experiences. A fabricated reviewCount is not a grey area — it is a policy violation. The practical consequences:

  • Pages become ineligible for star-rating rich results
  • Repeated violations can trigger manual actions affecting the entire domain
  • The fabricated signal is negative for E-E-A-T (trustworthiness specifically)

The correct schema for a site that provides one editorial review per tool is Review, not AggregateRating.

Problem 2: Missing FAQPage Schema

The FAQ page existed. The structured data for it did not. This meant the page was not eligible for FAQ rich results — expandable Q&A blocks that appear in search results and significantly increase a listing's visual footprint.

Adding FAQPage schema to an existing FAQ page with genuine questions and answers is one of the lowest-effort, highest-potential-value SEO additions available. There is no technical complexity — it is JSON that maps directly from the page's existing content.

Problem 3: Thin Author Schema

Blog post author fields pointed to an organisation entity with a name and nothing else:

"author": {
  "@type": "Organization",
  "name": "Shabelle Hub"
}

This is technically valid but provides minimal E-E-A-T signal. Google's quality guidelines weight author expertise and credibility for YMYL-adjacent content (health, finance, and by extension, software purchasing decisions). An author entity with a name and no other identifying information contributes less than one with a URL, a sameAs link to a professional profile, or a description of their expertise.


The Fixes

Fix 1: Replace AggregateRating With Review

In lib/seo.js, the getToolStructuredData function was updated:

// Before — fabricated
aggregateRating: {
  '@type': 'AggregateRating',
  ratingValue: tool.rating,
  reviewCount: tool.reviews, // fabricated field
  bestRating: 5,
  worstRating: 1,
},

// After — honest
review: {
  '@type': 'Review',
  reviewRating: {
    '@type': 'Rating',
    ratingValue: tool.rating,
    bestRating: 5,
    worstRating: 1,
  },
  author: {
    '@type': 'Organization',
    name: 'Shabelle Hub',
    url: 'https://shabellehub.com',
  },
},

The reviews field was removed from all tool data objects. The on-page display of {tool.reviews.toLocaleString()} reviews was replaced with Shabelle Hub Rating.

Fix 2: Add FAQPage Schema

The FAQ page at pages/faq.js now emits FAQPage structured data that maps from the page's content array:

const faqJsonLd = {
  '@context': 'https://schema.org',
  '@type': 'FAQPage',
  mainEntity: FAQS.map(f => ({
    '@type': 'Question',
    name: f.q,
    acceptedAnswer: {
      '@type': 'Answer',
      text: f.a,
    },
  })),
};

Every question and answer in the schema has a corresponding visible element on the page — a requirement of the FAQPage policy. The schema was not added until the visible content existed.

Fix 3: Improve BlogPosting Author Schema

Blog post structured data now uses a Person type for the author when a named author is available:

author: post.author?.name
  ? {
      '@type': 'Person',
      name: post.author.name,
      url: post.author.url || 'https://shabellehub.com/about',
    }
  : {
      '@type': 'Organization',
      name: 'Shabelle Hub',
      url: 'https://shabellehub.com',
    },

The url field on the author entity links to a page where the author's background and expertise can be verified. For Organization authors, the URL links to the About page, which describes the site's editorial process.


Schema Types and When to Use Them

A reference for the schema types relevant to a review and directory site:

| Schema Type | Use case | When NOT to use |

|-------------|----------|-----------------|

| AggregateRating | Site collects real user ratings | You have no user rating system |

| Review | Single editorial review by a named author or publisher | You want to aggregate multiple reviews |

| Rating | A numerical rating within a Review | Standalone — must be nested inside Review |

| FAQPage | Dedicated FAQ page | FAQ section on a non-FAQ page |

| BlogPosting | Blog articles | Product pages, tool listings |

| SoftwareApplication | Software product listing | Incorrect type for blog posts or categories |

| BreadcrumbList | Breadcrumb navigation | No breadcrumb UI on the page |

| WebSite | Homepage sitelinks search | Should only appear once, on the homepage |

| Organization | Organisation identity | Individual person pages |

The guiding principle: use the schema type that accurately describes what the page contains. Not the type that unlocks the most impressive rich result. Not the type that looks most authoritative. The type that matches the content.


Verifying Schema

Two tools for validation:

Google Rich Results Test (search.google.com/test/rich-results) — tests a live URL or HTML snippet and shows which rich results the page is eligible for. Also shows warnings for policy issues.

Schema Markup Validator (validator.schema.org) — validates the JSON-LD against schema.org specifications. Catches type errors, missing required fields, and structural problems.

Run both after any schema change. The Rich Results Test is more important for catching policy issues; the Markup Validator is more thorough for structural correctness.

For ShabelleHub, all tool pages, the FAQ page, and blog posts now pass both validators without warnings.


The Principle

Schema markup is a representation to Google of what your page contains. When that representation is accurate, it helps Google understand the content and potentially surface it as rich results. When it is inaccurate, it creates a trust gap between what the schema claims and what Google finds when it evaluates the page.

Google's systems are designed to detect this gap. The consequence is not just losing a rich result — it is a negative signal about the page's trustworthiness. Honest schema that accurately describes what exists is better than impressive schema that misrepresents what exists, even when the honest schema qualifies for fewer rich results.

A Review authored by Shabelle Hub, with an accurate rating and no fabricated review count, is correct. That is what ShabelleHub provides. The schema now says so.


*This article is part of the ShabelleHub Building in Public series.*

📬 Get the latest AI tool reviews

Expert picks and comparisons, weekly. No spam.

← Back to Blog