Aizii Learn · AI Search

[← Back to Learn](https://aizii.ai/learn)

# How to add product schema on a self-hosted site

On a self-hosted site you control the full stack: the templates, the build, the deployment, and the HTML the server sends. Adding product schema is therefore a code change in your own codebase, not a platform setting. You add a JSON-LD block to the product template so every product page renders it server side, and it ships with your next deploy. The one constraint shaping everything is that you also own every failure mode: nobody validates the markup for you, nobody keeps it in sync with price changes, and nobody stops a deploy from shipping broken JSON.

## Why a self-hosted site is different

There is no guardrail and no ceiling. Unlike Shopify or Wix, there is no theme system to fight and no locked markup to work around; unlike Squarespace, there is no plan gate. The product template is yours, the data layer is yours, and the rendered HTML is exactly what you emit, which means server-rendered JSON-LD is guaranteed as long as you put it in the template rather than injecting it with client-side JavaScript. The trade is responsibility. The markup is generated from your code, so a template bug, a bad deploy, or a data field that renders on the page but never reaches the JSON-LD block is entirely on you. Most self-hosted schema failures are data-plumbing failures, not syntax failures.

## Steps

**1\. Check what the server actually sends.** This matters more here than on any platform. Fetch a product page the way a crawler sees it, with curl or view-source, and search for `application/ld+json`. Do not trust the browser DOM: if your stack hydrates content with JavaScript, the DOM can show markup that was never in the initial HTML. If the block is missing from the raw response, AI crawlers cannot see it.

**2\. Add the block to the product template.** Put the JSON-LD script in the template or partial that renders your product pages (the layout, the view, or the component, depending on your stack), guarded so it only renders on product routes. Generate every value from the same data source that renders the visible page: the product record, the price service, the inventory check. A template that reads the price from one service for the page and a different one for the markup will eventually disagree with itself, and a price mismatch between markup and page is the most damaging schema failure there is.

**3\. Cover variants and stock status in the template logic.** If products have variants, the template must emit per-variant offers with per-variant availability. If a product can go out of stock, the availability value must be computed from live inventory at render time, not baked in at build time, unless your build reruns on every inventory change.

**4\. Deploy and verify the raw HTML.** Ship through your normal pipeline, then curl a staging or production product URL and confirm the block is in the response. Test a URL such as https://\[yourdomain.com\]/products/your-product, replacing yourdomain.com with your actual domain, in Google's Rich Results Test and the Schema Markup Validator. Include a variant page and an out-of-stock product.

**5\. Add validation to the pipeline.** Since no platform checks this for you, add a check that survives deploys: a test that fetches product pages and asserts the JSON-LD parses and carries price, currency, and availability, or at minimum a recurring manual validation pass after template changes. The most common regression is a redesign that moves the block, renames a data field, or drops it entirely.

### The fundamentals

-   •The complete JSON-LD reference this article builds on, see our [product schema guide](https://aizii.ai/learn/ai-search/how-to-add-product-schema-markup-for-ai-search)
-   •Whether AI crawlers can reach your pages at all, see our [robots.txt guide](https://aizii.ai/learn/ai-search/how-to-write-robots-txt-for-ai-search)
-   •A readable catalog summary for AI engines, see our [llms.txt guide](https://aizii.ai/learn/ai-search/how-to-write-a-good-llms-txt-file)

### A hypothetical example

Say you run a specialty foods store on a self-hosted stack you built with a small team. You curl a product page and find no JSON-LD at all. You add the block to the product view template, pulling name, price, and stock status from the same product record the page renders, and deploy. A month later a redesign renames the template partial and the block silently disappears. Your deploy check catches it because you added a test asserting every product page response contains a parseable Product block. That test is the difference between owning the stack and being owned by it.

## What this guide does not cover

This covers getting valid, server-rendered product markup onto your self-hosted product pages. It does not cover keeping that markup accurate as inventory changes (monitoring work, plus the pipeline checks above), getting AI crawlers to your pages past your own edge and bot rules, or letting an agent complete the checkout, which is the transaction layer and a separate job.

## Frequently Asked Questions

Where should I inject the schema markup on custom backend sites?

Inject the script tag inside the HTML head or right before the closing body tag of your product detail page template.

How should dynamic product data be formatted?

Serialize your backend product model to JSON and output it safely inside a script type='application/ld+json' block.

What character encoding is required for JSON-LD?

Serve your HTML and JSON-LD as UTF-8, and escape any special HTML characters to prevent parsing errors.

## Check your own brand now

Run the free scan. It takes seconds, no signup, and shows whether AI crawlers can read your product pages today: aizii.ai/aeo-scan

[Run the free scan](https://aizii.ai/aeo-audit)
