useSchemaOrg: Add Schema.org JSON-LD to Vue and Nuxt
Implementation overview
useSchemaOrg() adds typed, reactive Schema.org nodes to the document head. This guide explains node definitions, graph relationships, deduplication, framework imports, and server-rendered JSON-LD output.
The useSchemaOrg() composable adds one or more Schema.org nodes to the page.
useSchemaOrg(unheadInstance, input, options)
Example
Define an Article node:
useSchemaOrg(unheadInstance, [
defineArticle({
headline: 'My Blog Post',
image: '/images/post.jpg',
datePublished: new Date(),
})
])
Input
The input accepts one Schema.org node or an array of nodes. Nodes can come from define* helpers or be plain objects:
type UseSchemaOrgInput = Thing | Record<string, any> | Array<Thing | Record<string, any>>
Available node functions include:
defineWebSite(): Site-level metadatadefineWebPage(): Page-level metadatadefineArticle(): Blog posts and articlesdefineProduct(): E-commerce productsdefineOrganization(): Company/organization infodefinePerson(): Author/person profilesdefineBreadcrumb(): Navigation breadcrumbs- Browse all node helpers
Options
The second parameter accepts HeadEntryOptions for the generated head entry:
export interface HeadEntryOptions {
processTemplateParams?: boolean
tagPriority?: number | 'critical' | 'high' | 'low' | `before:${string}` | `after:${string}`
tagPosition?: 'head' | 'bodyClose' | 'bodyOpen'
key?: string
tagDuplicateStrategy?: 'replace' | 'merge'
head?: Unhead
onRendered?: (ctx: { renders: DomRenderTagContext[] }) => void | Promise<void>
}
Entry API
The useSchemaOrg composable returns an entry that you can patch or dispose.
const schemaEntry = useSchemaOrg(unheadInstance, [
defineWebPage({ name: 'My Page' })
])
// removes the schema nodes
schemaEntry.dispose()
XSS safety
The rendered JSON-LD is escaped so input cannot close the script element. Unhead does not validate node values or sanitize HTML contained in them.
Do not pass unknown or untrusted third-party input without validating and sanitizing it first.
Common Questions
How do I add multiple schema types to a page?
Pass an array to useSchemaOrg(); each item becomes a node in the graph.
useSchemaOrg(unheadInstance, [
defineWebPage({ name: 'Product Page' }),
defineProduct({
name: 'Widget',
offers: { price: 29.99, priceCurrency: 'USD' },
}),
defineBreadcrumb({
itemListElement: [
{ name: 'Home', item: '/' },
{ name: 'Products', item: '/products' },
]
})
])
Do I need to set @id manually?
Usually not. Helpers with primary roles use stable IDs, while other nodes receive numbered IDs. Set @id when you need a specific identity or several separately addressable nodes.
How does Schema.org get page metadata?
The plugin collects metadata from <title>, the meta description, the canonical link's host, og:image, <html lang>, and templateParams.schemaOrg. Each resolver chooses which values to inherit.
See Also
- useHead(): General head management
- useSeoMeta(): SEO meta tag management
- Schema.org Nodes: How to define and relate schema types
Site Search
Add a SearchAction to WebSite schema with defineSearchAction() and describe your internal search URL template.
Article Schema - JSON-LD Guide & Examples
Implement Article structured data with Unhead. JSON-LD examples for BlogPosting, NewsArticle, TechArticle with datePublished and author markup.