Fix: Invalid structured data
Invalid JSON-LD is worse than no JSON-LD because it creates a silent failure. When you omit structured data entirely, search engines fall back to parsing your HTML. When you inject malformed structured data, you assume you have secured rich results — but Google's crawler drops the payload entirely upon hitting a syntax error or a missing @context.
Indxel splits structured data validation into two strict rules. The structured-data-valid rule (weight: 2/100) catches invalid JSON syntax, missing @context, and missing @type declarations. The structured-data-complete rule (weight: 4/100) verifies that your specific schema type contains the fields required by Google's Rich Results guidelines. Failing both rules deducts 6 points from your page score.
Search Console will not immediately notify you if a new page ships with a trailing comma in its JSON-LD script tag. The crawler simply aborts parsing that block. You must catch these validation errors at build time.
How do you detect invalid structured data?
Run npx indxel check against your local server or production URL to scan for JSON-LD syntax and schema errors. The CLI extracts all <script type="application/ld+json"> blocks, parses the JSON, and validates the schema against the official schema.org specifications.
$ npx indxel check http://localhost:3000/blog/how-to-fix-seo
Running Indxel SEO checks...
/blog/how-to-fix-seo
⚠ structured-data-valid: JSON-LD missing required "@context" property.
⚠ structured-data-complete: Type "Article" is missing required field "author".
⚠ structured-data-complete: Type "Article" is missing required field "datePublished".
Score: 94/100
Found 3 warnings.The structured-data-valid rule flags a WARNING rather than an ERROR because the page remains indexable. However, invalid structured data guarantees you will not receive rich snippets (like star ratings, recipe cards, or FAQ accordions) in search results.
How do you fix invalid JSON-LD?
Fix invalid JSON-LD by ensuring valid JSON syntax, declaring "@context": "https://schema.org", specifying a valid @type, and providing all required fields for that specific schema.
The most common failure occurs when developers manually construct JSON strings instead of relying on standard JSON serialization.
The broken implementation
Here is an example of invalid structured data that fails the Indxel check. It is missing the @context, omits the required author field for the Article type, and uses a trailing comma which invalidates the JSON syntax.
<script type="application/ld+json">
{
"@type": "Article",
"headline": "Fix Invalid Structured Data",
"datePublished": "2024-05-12T08:00:00Z",
}
</script>Next.js App Router fix
In the Next.js App Router, inject JSON-LD inside a <script> tag in your page.tsx. Always use JSON.stringify to serialize the object. This prevents syntax errors from trailing commas and safely escapes quotation marks in your dynamic data.
For type safety, install the schema-dts package. This ensures TypeScript warns you if you misspell a schema property before Indxel even runs.
// app/blog/[slug]/page.tsx
import { Article, WithContext } from 'schema-dts';
export default function BlogPost({ params }: { params: { slug: string } }) {
// 1. Define the schema with strict TypeScript definitions
const jsonLd: WithContext<Article> = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Fix Invalid Structured Data",
author: [{
"@type": "Person",
name: "Jane Doe",
url: "https://indxel.com/team/jane"
}],
datePublished: "2024-05-12T08:00:00Z",
};
return (
<section>
{/* 2. Safely inject stringified JSON */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<h1>Fix Invalid Structured Data</h1>
<p>Post content goes here...</p>
</section>
);
}Next.js Pages Router fix
If you are maintaining a Next.js Pages Router application, structured data should be injected into the <Head> component. The serialization rules remain exactly the same.
// pages/blog/[slug].tsx
import Head from 'next/head';
export default function BlogPost({ post }) {
const jsonLd = {
"@context": "https://schema.org",
"@type": "Article",
"headline": post.title,
"author": {
"@type": "Person",
"name": post.authorName
},
"datePublished": post.createdAt
};
return (
<>
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
</Head>
<article>
<h1>{post.title}</h1>
</article>
</>
);
}The Indxel SDK approach
If you use the Indxel React SDK, validation happens automatically. The <StructuredData> component enforces @context injection and validates required fields at runtime in development mode, throwing a React error before you commit the code.
import { StructuredData } from '@indxel/react';
export default function BlogPost() {
return (
<section>
<StructuredData
type="Article"
data={{
headline: "Fix Invalid Structured Data",
author: { name: "Jane Doe" }, // Indxel warns if this is missing
datePublished: "2024-05-12T08:00:00Z"
}}
/>
<h1>Post Content</h1>
</section>
);
}How do you prevent invalid structured data in CI?
Block invalid JSON-LD from reaching production by adding npx indxel check --ci to your GitHub Actions workflow or your Vercel build command.
When you run Indxel in CI mode, any warning for structured-data-valid or structured-data-complete will exit with a non-zero status code, failing the build.
GitHub Actions integration
Add this step to your pull request workflow. The --diff flag ensures Indxel only checks the pages affected by the current branch, keeping CI times under 10 seconds.
# .github/workflows/seo-check.yml
name: Indxel SEO Guard
on: [pull_request]
jobs:
validate-seo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Check SEO rules
run: npx indxel check --ci --diffVercel build integration
To fail Vercel deployments before they go live, modify your build script in package.json. Vercel will execute the build, run the Indxel check against the output directory, and abort the deployment if structured data is invalid.
{
"scripts": {
"dev": "next dev",
"build": "next build",
"postbuild": "indxel check .next/server/app --ci",
"start": "next start"
}
}If you have legacy pages with incomplete structured data that you cannot fix immediately, you can bypass the build failure by adding --ignore-rule structured-data-complete to your CI command. Do not ignore structured-data-valid, as malformed JSON breaks the entire script block.
What are the edge cases for structured data validation?
Dynamic data escaping, missing schema-specific required fields, and entity array resolution are the three most common edge cases that break JSON-LD payloads.
Unescaped quotes in dynamic content: Never use template literals to build JSON-LD strings. If a user's display name or a blog post title contains a double quote ("Fixing "Bad" SEO"), standard string interpolation will output invalid JSON. JSON.stringify automatically escapes these characters.
Multiple entities on one page: If your page contains multiple distinct schemas (e.g., a Product and a BreadcrumbList), do not create multiple <script> tags. Google prefers a single script tag containing an array or a @graph object.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Product",
"name": "Indxel Pro"
},
{
"@type": "BreadcrumbList",
"itemListElement": [...]
}
]
}
</script>Nested entity validation: Google's rich result parsers require specific nested types. Declaring "author": "Jane Doe" is technically valid schema.org syntax, but Google's Article rich results require author to be an object: "author": { "@type": "Person", "name": "Jane Doe" }. The Indxel structured-data-complete rule enforces Google's stricter requirements, not just the base schema.org specs.
Related rules
missing-structured-data: Fails when Indxel cannot find any<script type="application/ld+json">block on the page.duplicate-structured-data: Fails when the exact same schema entity is injected multiple times, which commonly happens when a layout file and a page file both inject the same default Organization schema.
FAQ
What are the required fields for common schema types?
Article requires headline, author, and datePublished. Product requires name and description. FAQ requires mainEntity. Organization requires name and url. BreadcrumbList requires itemListElement. Omission of any of these triggers a structured-data-complete warning.
Does Indxel check syntax or schema completeness?
Both. The structured-data-valid rule validates pure JSON syntax, checks for the @context declaration, and ensures a @type exists. The structured-data-complete rule maps the declared @type against Google's documentation to verify all required fields are present.
Can I use Microdata instead of JSON-LD?
Google strongly prefers JSON-LD, and Indxel only validates JSON-LD. Microdata litters your DOM with itemprop attributes, forcing you to interleave SEO metadata with your rendering logic. This makes React components brittle. Always use JSON-LD.
How do I test structured data locally before deploying?
Run npx indxel check localhost:3000 while your dev server is running. You do not need to deploy to a public URL or use tunneling software to test JSON-LD validity with Indxel, which is required if you rely solely on Google's Rich Results Test tool.
Frequently asked questions
What are the required fields for common schema types?
Article: headline, author, datePublished. Product: name, description. FAQ: mainEntity. Organization: name, url. BreadcrumbList: itemListElement. HowTo: name, step.