How to add JSON-LD structured data to your website
JSON-LD (JavaScript Object Notation for Linked Data) is the format Google, Bing, and other search engines use to understand your page content. agentmarkup injects schema.org JSON-LD into your HTML pages at build time for Vite, Astro, and Next.js with XSS-safe serialization and type-safe presets.
What is JSON-LD structured data?
Structured data tells search engines exactly what your page is about. Instead of guessing from HTML content, search engines read your JSON-LD and understand that a page is a Product with a price, an Article with a publish date, or an Organization with a logo.
This powers rich results in Google Search, including star ratings, FAQ dropdowns, product cards, and knowledge panels. Without structured data, search engines can only guess at your page content.
Built-in schema.org presets
agentmarkup includes 6 type-safe presets for common structured data types. Each preset validates required fields at build time and generates spec-compliant JSON-LD.
| Preset | Schema type | Use case |
|---|---|---|
webSite | WebSite | Site-level schema with optional search action |
organization | Organization | Company or brand identity |
article | Article | Blog posts, news, content pages |
faqPage | FAQPage | Question and answer pages |
product | Product | E-commerce product pages |
offer | Offer | Pricing and availability |
Using presets
Apply schemas globally (every page) or per-page. Global schemas like webSite and organization go in globalSchemas. Page-specific schemas go in pages. The schema config is adapter-agnostic, so the same object works with @agentmarkup/vite, @agentmarkup/astro, and @agentmarkup/next.
const agentmarkupConfig = {
site: 'https://myshop.com',
name: 'My Shop',
globalSchemas: [
{ preset: 'webSite', name: 'My Shop', url: 'https://myshop.com' },
{ preset: 'organization', name: 'My Shop', url: 'https://myshop.com', logo: '/logo.png' },
],
pages: [
{
path: '/faq',
schemas: [{
preset: 'faqPage',
url: 'https://myshop.com/faq',
questions: [
{ question: 'Do you ship internationally?', answer: 'Yes, to 50+ countries.' },
],
}],
},
],
}Framework wrappers
After defining the shared schema config, pass it into the adapter for the framework that owns your final output:
// Vite
import { defineConfig } from 'vite'
import { agentmarkup } from '@agentmarkup/vite'
export default defineConfig({
plugins: [agentmarkup(agentmarkupConfig)],
})
// Astro
import { defineConfig } from 'astro/config'
import { agentmarkup } from '@agentmarkup/astro'
export default defineConfig({
integrations: [agentmarkup(agentmarkupConfig)],
})
// Next.js
import type { NextConfig } from 'next'
import { withAgentmarkup } from '@agentmarkup/next'
const nextConfig: NextConfig = {
output: 'export',
}
export default withAgentmarkup(agentmarkupConfig, nextConfig)Custom schemas
You can use any schema.org type by passing an object with an @type field. agentmarkup automatically adds the @context and handles serialization.
pages: [
{
path: '/products/wallets',
schemas: [{
'@type': 'Product',
name: 'Classic Leather Wallet',
description: 'Full-grain leather bifold wallet.',
image: 'https://myshop.com/images/wallet.jpg',
sku: 'WALLET-001',
offers: {
'@type': 'Offer',
price: '89',
priceCurrency: 'USD',
availability: 'https://schema.org/InStock',
},
}],
},
]XSS-safe output
agentmarkup escapes dangerous characters (<, >, &, ') to unicode escapes before injecting JSON-LD into HTML. This prevents XSS attacks through structured data injection.
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"WebSite","name":"My Shop","url":"https://myshop.com"}
</script>Build-time validation
Every schema is validated during build. Missing required fields produce errors. Missing recommended fields produce warnings. You see exactly what needs fixing in your terminal before deploying.
- Required field errors: Product without
name, Article withoutheadline - Recommended field warnings: Organization without
logo, Product withoutsku - Custom schema checks: Every custom schema must have an
@typefield
Combined with llms.txt generation, markdown mirrors, and AI crawler management, this gives your website a fuller machine-readable surface instead of relying on structured data alone.
Frequently asked questions
Do I need JSON-LD if I already have meta tags?
Yes. Meta tags (title, description) help search engines understand a single page. JSON-LD tells them what kind of thing the page represents (a product, an article, an FAQ) with structured fields they can use for rich results.
Can I add multiple schemas to one page?
Yes. Use the pages config to add multiple schemas per path. Each schema generates its own <script type="application/ld+json"> tag. Global schemas are also added to every page.
What if I need a schema type that is not a preset?
Pass any object with an @type field. agentmarkup will add @context automatically and serialize it safely. Presets just save you from remembering required fields.