🛠️ JSON-LD + JavaScript Frameworks: Mastering Dynamic Schema
In the era of Single Page Applications (SPA), traditional SEO methods often fall short. When content changes dynamically without a page reload, your structured data must follow suit. If Googlebot crawls your site and finds "Home" schema while looking at a "Product" page, your rich results will vanish.
📑 Quick Navigation
The Challenge: Why "Static" Fails
In a traditional WordPress site, the server sends fresh HTML for every URL. In frameworks like React or Vue, the shell remains the same while components swap. Without manual updates, search engines might read metadata from the previous route.
1. Next.js: Using Next-SEO
Next.js is the gold standard for SEO because of Server-Side Rendering (SSR). The next-seo library is the most efficient way to manage this.
import { ProductJsonLd } from 'next-seo';
const ProductPage = ({ product }) => (
<>
{product.name}
>
);
2. React: Advanced Dynamic Injection Hook
For standard React SPAs, you must inject the script into the <head> and clean it up when the component unmounts to prevent duplicate markup.
import { useEffect, useRef } from 'react';
/**
* Custom hook for managing dynamic JSON-LD in React SPAs
* @param {Object} data - JSON-LD structured data
* @param {string} [id='dynamic-json-ld'] - Unique script ID
*/
const useJsonLd = (data, id = 'dynamic-json-ld') => {
const scriptRef = useRef(null);
useEffect(() => {
// Remove existing script if it exists
const existingScript = document.getElementById(id);
if (existingScript) {
existingScript.remove();
}
// Create new script element
const script = document.createElement('script');
script.type = 'application/ld+json';
script.id = id;
script.innerHTML = JSON.stringify(data, null, 2);
document.head.appendChild(script);
scriptRef.current = script;
return () => {
if (scriptRef.current && document.head.contains(scriptRef.current)) {
scriptRef.current.remove();
}
};
}, [data, id]);
};
// Usage in component:
const ProductPage = ({ product }) => {
const productSchema = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
description: product.description,
brand: {
'@type': 'Brand',
name: 'YourBrand'
}
};
useJsonLd(productSchema);
return {/* Your component JSX */};
};
3. Vue & Nuxt.js: Using Unhead
Nuxt 3 uses Unhead natively. You can use the useHead composable to manage your JSON-LD reactively.
<template>
<div>
<h1>{{ article.title }}</h1>
</div>
</template>
<script setup>
import { useHead } from '@unhead/vue';
const article = {
title: 'Dynamic Vue SEO',
description: 'Learn how to implement JSON-LD in Vue.js applications',
publishedDate: '2026-01-18'
};
useHead({
title: article.title,
script: [
{
type: 'application/ld+json',
innerHTML: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'Article',
headline: article.title,
description: article.description,
datePublished: article.publishedDate,
author: {
'@type': 'Organization',
name: 'JSON-LD Generator'
}
})
}
]
});
</script>
Common Pitfalls
- ❌ Script Bloat: Multiple plugins or unmount failures adding duplicate schema.
- ❌ Missing Fields: Forgetting required fields like
publisherorimage. - ❌ Execution Lag: If your JSON-LD is injected too late via client-side JS, some crawlers might miss it.
- ❌ Invalid JSON: Trailing commas or undefined values breaking the JSON structure.
- ❌ Missing @context: Forgetting the schema.org context declaration.
🎯 Pro-Tip: Always Verify Your Implementation
Even with perfect code, dynamic JSON-LD can fail if Googlebot doesn't execute your JavaScript in time. Always use the 'URL Inspection tool' in Google Search Console to see the 'Rendered HTML'. This is the only way to be 100% sure your dynamic JSON-LD was executed. For performance optimization, check our guide on Where to Put JSON-LD for Maximum Performance.
Frequently Asked Questions
Does Google execute JS for JSON-LD?
Yes, Googlebot processes JavaScript, but there can be a delay. SSR is always preferred for critical SEO data. The second wave of indexing executes JavaScript, but for time-sensitive content, server-side generation is safer.
Can I use multiple schema types?
Yes, you can have Article and FAQPage on the same page, but avoid using different plugins for each to prevent conflicts. Use a single script with an array of schema objects for better performance:
[
{"@context": "...", "@type": "Article", ...},
{"@context": "...", "@type": "FAQPage", ...}
]
Should I use JSON-LD or Microdata with frameworks?
JSON-LD is the clear winner for JavaScript frameworks. It separates data from markup, making it easier to manage dynamically. Microdata requires inline HTML attributes that conflict with component-based architectures. Read our comparison: JSON-LD vs Microdata: Ultimate 2026 Showdown.
🚀 Generate Framework-Ready JSON-LD
Get validated, clean code for your React or Vue components in seconds. Our generator supports all major framework patterns.
Generate Now →Want to dive deeper? Check our complete guide on JSON-LD placement strategies.