) within string values — use backslash-forward-slash."}} ]}, {"@type":"BreadcrumbList","itemListElement":[ {"@type":"ListItem","position":1,"name":"Home","item":"https://aiwebpageseo.com/seo-audit-platform.html"}, {"@type":"ListItem","position":2,"name":"Learning Hub","item":"https://aiwebpageseo.com/learning-hub.html"}, {"@type":"ListItem","position":3,"name":"JSON Checker Fixes","item":"https://aiwebpageseo.com/aipageseo-demo-pages/json-checker-fixes-index.html"}, {"@type":"ListItem","position":4,"name":"Fix JSON-LD Syntax","item":"https://aiwebpageseo.com/aipageseo-demo-pages/how-to-fix-json-syntax.html"} ]} ]}
/ JSON Checker Fixes / JSON Syntax

How to Fix JSON-LD Syntax Errors

JSON-LD syntax errors mean Google, Bing and every other crawler ignores your structured data entirely. One unescaped quote in a product description breaks the whole schema block — no rich snippet, no knowledge graph, no anything. Most syntax errors come from template engines interpolating user content without escaping. The fix is build JSON-LD as real objects, serialise with JSON.stringify, and validate at build time.

1. Find broken JSON-LD

Step 1
Run the JSON Checker
Run the JSON Checker. Each finding shows: URL, error message, the line/column position of the failure, and a snippet of the surrounding JSON.
Step 2
Cross-check with Schema.org Validator
validator.schema.org and Google's Rich Results Test both highlight JSON syntax errors before semantic checks. The error messages from these tools are typically clearer than the JSON Checker's.
Step 3
Pattern-match the errors
Most syntax errors cluster around a few patterns:
  • Unescaped double quotes in string values
  • Trailing commas
  • Newlines inside string values
  • Single quotes instead of double
  • Closing </script> within a string value
Fix the pattern in the template; many pages get fixed at once.

2. The escape-quote problem

<!-- BROKEN: title contains double quote -->
<script type="application/ld+json">
{
  "@type": "Article",
  "headline": "Apple's "iPhone" announcement"
}
</script>

<!-- FIXED: escape inner quotes -->
<script type="application/ld+json">
{
  "@type": "Article",
  "headline": "Apple's \"iPhone\" announcement"
}
</script>

Or better — use a typographic quote which doesn't need escaping:

"headline": "Apple's “iPhone” announcement"

3. Closing script tag inside JSON string

If a string value contains </script>, the browser thinks the JSON-LD block ended — the rest of your JSON gets treated as HTML and breaks.

<!-- BROKEN -->
<script type="application/ld+json">
{
  "description": "Read about </script> tag use in HTML"
}
</script>

<!-- FIXED — escape the forward slash -->
<script type="application/ld+json">
{
  "description": "Read about <\/script> tag use in HTML"
}
</script>

JSON.stringify doesn't escape forward slashes by default. Add post-processing:

JSON.stringify(data).replace(/<\/script/gi, '<\\/script')

4. The right way: build from real objects

Most syntax errors disappear when you stop hand-writing JSON-LD in templates.

Wrong: template string concatenation

<!-- Liquid template — fragile -->
<script type="application/ld+json">
{
  "@type": "Product",
  "name": "{{ product.title }}",
  "description": "{{ product.description }}"
}
</script>
<!-- If product.title contains a quote, this breaks -->

Right: serialise an object

<!-- Build the object in code, serialise once -->
<script type="application/ld+json">
{{ product_schema | json }}
</script>

# In your controller / data layer:
product_schema = {
  '@context': 'https://schema.org',
  '@type': 'Product',
  'name': product.title,
  'description': product.description
}

The | json filter (Jekyll), {!! json_encode($data) !!} (Laravel), JSON.stringify(data) (Node), json.dumps(data) (Python) — each properly escapes quotes, newlines, special characters.

Next.js example

function ProductPage({ product }) {
  const schema = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name: product.title,
    description: product.description,
    image: product.images[0],
    offers: {
      '@type': 'Offer',
      price: product.price,
      priceCurrency: 'USD',
      availability: product.inStock 
        ? 'https://schema.org/InStock' 
        : 'https://schema.org/OutOfStock'
    }
  };
  
  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ 
          __html: JSON.stringify(schema).replace(/<\/script/g, '<\\/script')
        }}
      />
      <ProductContent product={product} />
    </>
  );
}

5. Validate at build time

Catch invalid JSON-LD in CI before it ships.

# scripts/validate-json-ld.js
const fs = require('fs');
const path = require('path');
const cheerio = require('cheerio');

const errors = [];
const htmlFiles = require('glob').sync('dist/**/*.html');

for (const file of htmlFiles) {
  const $ = cheerio.load(fs.readFileSync(file, 'utf8'));
  $('script[type="application/ld+json"]').each((i, el) => {
    try {
      JSON.parse($(el).html());
    } catch (e) {
      errors.push(`${file}: ${e.message}`);
    }
  });
}

if (errors.length) {
  console.error('Invalid JSON-LD found:');
  errors.forEach(e => console.error(' ', e));
  process.exit(1);
}
console.log('All JSON-LD valid');

6. Common JSON syntax errors

ErrorCauseFix
Unexpected token "Unescaped quote in stringUse JSON.stringify, not concat
Unexpected token ,Trailing comma after last propertyRemove trailing commas
Unexpected endMissing closing brace/bracketMatch every open with close
Unexpected token 'Single quotes usedReplace with double quotes
Bad control characterRaw newline in stringUse \n escape sequence
💡 Treat JSON-LD as data, not text. Build a typed model (or schema-DTS in TypeScript), populate it from your CMS data, serialise once at the boundary. Most JSON syntax errors disappear because the serialiser handles edge cases correctly.

📋 Re-run the JSON Checker

Verify all JSON-LD blocks parse correctly.

Run JSON Checker →
Related Guides: JSON Checker Fixes  ·  Fix Schema Required Fields  ·  Fix Schema Types  ·  JSON Checker Guide
💬 Got a problem?