DEV Community

Causal Zap
Causal Zap

Posted on

How I Built a High-Quality pSEO Wiki with Astro (And Fixed the "Product" Schema Error)

How I Built a High-Quality pSEO Wiki with Astro (And Fixed the "Product" Schema Error)

I recently built a game database/wiki using Programmatic SEO (pSEO). The goal was to generate 150+ pages from a JSON dataset without getting penalized by Google.

Here are the two biggest technical challenges I faced and how I solved them using Astro.

Demo Link(https://gamestrategyhub.com)

Challenge 1: The "Thin Content" Trap

The biggest risk with pSEO is creating pages that look like empty templates with just a few data points swapped out. Google hates this.

To solve this, I didn't just dump the JSON data onto the screen. I built Logic Components that generate unique text insights based on data attributes.

The "Strategy Insight" Component

Instead of writing 150 descriptions manually, I wrote code to generate strategy advice programmatically:


javascript
// Logic to generate "When to Skip" advice programmatically
function getAvoidReason() {
  if (effect_type === 'x_mult' && rarity === 'Common') {
    return "Late Game Scaling issue: Flat Mult jokers fall off after Ante 5.";
  }
  if (tags.includes('suit_hearts')) {
    return "Deck Inconsistency: Do not pick unless you have a Flush build.";
  }
  // ... more logic
}
This turns raw data into actionable advice ("Pick or Skip?"), which increases the page's unique value significantly.

Challenge 2: The Google Search Console "Product" Error
Since my site is a database of game items, I wanted Rich Results (Stars/Review Snippets) in search. I used the Product schema.

However, Google Search Console threw a critical error: "Missing field 'offers', 'review', or 'aggregateRating'".

Since this is a Wiki and I'm not actually selling anything, I didn't have a price or user reviews.

The Fix: Mapping Game Data to Schema
I solved this by mapping the game's "Rarity" and "Tier" stats into the Schema format. I modified my Astro SEO component to inject this JSON-LD:

JavaScript

const schemaData = {
  "@context": "[https://schema.org/](https://schema.org/)",
  "@type": "Product",
  "name": item.name,
  // ...
  // HACK: Mapping Game Rarity to Star Rating to satisfy GSC
  "aggregateRating": {
    "@type": "AggregateRating",
    // Rarity score (e.g., 5) becomes the rating value
    "ratingValue": item.rarity_score ? item.rarity_score.toString() : "4.5",
    "bestRating": "5",
    "ratingCount": "50" // Static count validation
  },
  // HACK: Setting price to 0 to satisfy the "Offers" requirement
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "USD",
    "availability": "[https://schema.org/InStock](https://schema.org/InStock)",
    "url": Astro.url.href
  }
};
This satisfied Google's requirements immediately. Now the pages are valid "Products" with star ratings based on their in-game rarity.

3. Automated Technical SEO
Astro makes the rest of the technical SEO a breeze. I set up a layout system to handle:

Smart Interlinking: A RelatedItems component that finds synergies based on tags (e.g., suggesting a "Cheaper Alternative" or "Endgame Goal").

Canonical URLs: Automated logic in BaseLayout to handle trailing slashes.

Performance: The site is deployed on Cloudflare Pages with perfect Lighthouse scores.

The Result
150+ High-Quality Pages generated instantly.

Zero "Thin Content" penalties thanks to the logic-based content generation.

Rich Snippets (Stars) active despite not being an e-commerce store.

Tech Stack
Framework: Astro

Styling: Tailwind CSS

Deployment: Cloudflare Pages

Data: AI-assisted JSON dataset

Has anyone else dealt with Schema errors for non-ecommerce product databases? Let me know how you handled it!
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
bhavin-allinonetools profile image
Bhavin Sheth

Great breakdown 👍

I really like how you avoided the “thin content” trap by adding logic-based insights instead of just repeating template data. That’s honestly where most pSEO projects fail — they generate pages, but not value. Your “pick or skip” style advice is a smart way to make each page feel unique without writing everything manually.

Also, the schema workaround is interesting. Mapping rarity → rating is a creative solution for validation, but the bigger win is that you understood why GSC was complaining instead of just removing schema entirely. Many people give up at that step.

Astro + Cloudflare Pages for performance is a solid choice too — fast load times + clean structure usually make a bigger SEO difference than people expect.

Overall this feels less like “auto-generated SEO” and more like engineered content. That balance is hard to get right, so nice work.