I'm building a business website in Next.js (App Router) and want to add JSON-LD structured data across different page types: Organization on all pages, Service on service pages, and BlogPosting on blog posts.
My current approach is a reusable base schema (Organization and WebSite) in the root layout, plus page-specific schema injected in each page component:
export default function Page() {
const schema = {
"@context": "https://schema.org",
"@type": "Service",
name: "SEO Services",
provider: { "@id": "https://example.com/#organization" },
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
{/* page content */}
</>
);
}
Questions:
1. Is this the recommended way to inject JSON-LD in the App Router, or is there a cleaner pattern?
2. How should I link page-level schema to the base Organization schema using @id so Google treats them as one entity?
3. Is there any risk of duplicate or conflicting schema when both the layout and the page output JSON-LD?
4. What is the best way to validate it at scale (Rich Results Test, Search Console, or automated checks in CI)?
Any examples or best practices would be appreciated.