--- title: useSchemaOrg() description: 'Add Schema.org structured data with useSchemaOrg(). Pass defineArticle(), defineProduct(), and other schema nodes for Google Rich Results.' --- The `useSchemaOrg()`{lang="ts"} composable is the primary way to add Schema.org structured data to your pages. **Quick Start:** ```ts useSchemaOrg([ defineWebSite({ name: 'My Site' }), defineWebPage({ name: 'Home' }) ]) ``` ```ts useSchemaOrg(input, options) ``` ## Example Define an article with structured data for Google Rich Results: ```ts useSchemaOrg([ defineArticle({ headline: 'My Blog Post', image: '/images/post.jpg', datePublished: new Date(), }) ]) ``` ## Input The input accepts an array of Schema.org node definitions created using `define*` functions: ```ts type SchemaOrgInput = SchemaOrgNode | SchemaOrgNode[] ``` Available node functions include: - `defineWebSite()` - Site-level metadata - `defineWebPage()` - Page-level metadata - `defineArticle()` - Blog posts and articles - `defineProduct()` - E-commerce products - `defineOrganization()` - Company/organization info - `definePerson()` - Author/person profiles - `defineBreadcrumb()` - Navigation breadcrumbs - And [many more](/docs/schema-org/api/schema/) ## Options The second parameter to `useSchemaOrg` is the `HeadEntryOptions`. This allows you to apply options to the entry, meaning all tags that exist within the `input`. ```ts export interface HeadEntryOptions { processTemplateParams?: boolean tagPriority?: number | 'critical' | 'high' | 'low' | `before:${string}` | `after:${string}` tagPosition?: 'head' | 'bodyClose' | 'bodyOpen' mode?: RuntimeMode transform?: (input: unknown) => unknown head?: Unhead } ``` ### `mode` This lets you specify which mode the head should be applied in. By default, entries are rendered in both server and client. If you'd like to only use a specific mode you can set the `mode` option to either `server` or `client`. If you intend to server render tags you should instead opt for the `useServerHead` composable. ## Entry API The `useSchemaOrg` composable returns an API to manage the lifecycle of the schema entry. Using this you can either `patch` or `dispose` of the entry. ```ts const schemaEntry = useSchemaOrg([ defineWebPage({ name: 'My Page' }) ]) // removes the schema nodes schemaEntry.dispose() ``` ## XSS safety The `useSchemaOrg` function only applies minimal sanitization on input to improve the developer experience. Be careful, **do not** use this function with any unknown / third party input, that isn't sanitised. It is not possible to guarantee that the output is safe when dealing with unknown input. If you need XSS safety, sanitise your input or look at using the [useSeoMeta](/docs/head/api/composables/use-seo-meta) or [useHeadSafe](/docs/head/api/composables/use-head-safe) composables instead. If you're having issues working around the default nodes, you should disable them. ```ts // nuxt.config.ts export default defineNuxtConfig({ schemaOrg: { defaults: false } }) ``` ## 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. ```ts useSchemaOrg([ defineWebPage({ name: 'Product Page' }), defineProduct({ name: 'Widget', price: 29.99 }), defineBreadcrumb({ itemListElement: [ { name: 'Home', item: '/' }, { name: 'Products', item: '/products' }, ] }) ]) ``` ### Do I need to set @id manually? No, Unhead automatically generates unique IDs and links related nodes. ### How does Schema.org get page metadata? It automatically infers data from your `` tags like ``, meta description, canonical URL, and og:image. ## See Also - [useHead()](/docs/head/api/composables/use-head) - General head management - [useSeoMeta()](/docs/head/api/composables/use-seo-meta) - SEO meta tag management - [Schema.org Nodes](/docs/schema-org/api/schema/) - All available schema types