--- title: Unhead Schema.org description: Learn more about Unhead Schema.org. navigation: title: Introduction --- ## What is Unhead Schema.org? Unhead Schema.org automatically generates valid JSON-LD structured data for Google Rich Results. Instead of manually writing complex JSON-LD, you use simple TypeScript functions like `defineArticle()` or `defineProduct()` that handle validation, URL resolution, and Google requirements automatically. ### Quick Start ```ts import { defineArticle, useSchemaOrg } from '@unhead/schema-org/@framework' // Generates complete Article JSON-LD with all required Google fields useSchemaOrg([ defineArticle({ headline: 'My Blog Post', image: '/images/post.jpg', datePublished: new Date(), }) ]) ``` ## Background With Unhead Schema.org you can inject a Schema.org graph into your page. Wrapper functions have been added to make opting in to [Google Rich Results](https://developers.google.com/search/docs/head/guides/core-concepts/search-gallery) nodes easier. For officially supported nodes, when the graph is being resolved it will apply a number of transforms to ensure the data is valid for Google. Otherwise, you can provide your own custom nodes that are passed through as is. ## How does Schema.org get page data? When resolving the graph, the package will inject config from the site and page level to reduce the amount of boilerplate. For example, if you have a ``{lang="html"} on your page, then it's likely we can use this same title to generate the Schema.org WebPage's `name`. The following inferences are from your `<head>`{lang="html"} data: - `inLanguage` - `<html lang="en">`{lang="html"} (`en`) - `name` - `<title>test`{lang="html"} (`test`) - `description` - ``{lang="html"} (`test`) - `url` - ``{lang="html"} (`https://example.com`) - `image` - ``{lang="html"} (`https://example.com/image.jpg`) Otherwise, they will come from your [Schema.org Params](/docs/schema-org/guides/core-concepts/params). ## How are duplicate nodes handled? For certain nodes, only one of them can exist at once. For example, a page can only have one `WebPage` node. When resolving the graph, the package will dedupe nodes based on the `@id` of the node. ## How are values transformed? There's numerous resolvers available to help minimise the work in maintaining and developing Schema. ::note In code examples, `@unhead/schema-org/@framework` is a placeholder. Replace `@framework` with your framework: `vue`, `react`, etc. :: ### URL Transformer Any URL field allows a relevant link to be provided. This link will either be prefixed with the canonical host or the canonical page URL. ```ts import { defineComment } from '@unhead/schema-org/@framework' defineComment({ text: 'This is really cool!', author: { name: 'Harlan Wilton', url: '/user/harlan-wilton', } }) ``` ```json [ { "@id": "https://example.com/#/schema/person/1230192103", "@type": "Person", "name": "Harlan Wilton", "url": "https://example.com/user/harlan-wilton" }, { "@id": "https://example.com/#/schema/comment/2288441280", "@type": "Comment", "author": { "@id": "https://example.com/#/schema/person/1230192103" }, "text": "This is really cool!" } ] ``` ### Image Transformer Uses the same relative link logic as the URL transformer. Additionally, single string images will be transformed to an [ImageObject](https://schema.org/ImageObject) and added as a root node and an applicable link to the `@id` will be added. ```ts import { defineWebPage } from '@unhead/schema-org/@framework' defineWebPage({ image: '/my-image.png', }) ``` ```json { "@id": "https://example.com/#/schema/image/1571960974", "@type": "ImageObject", "contentUrl": "https://example.com//my-image.png", "url": "https://example.com//my-image.png" } ``` ### ID Transformer Providing an `@id` for a Schema node is sometimes useful to setup your own relations. When configuring the `@id` you can provide it as a simple string beginning with `#`. The ID will be resolved to use the canonical host or the canonical page path as a prefix. ```ts import { defineBreadcrumb } from '@unhead/schema-org/@framework' defineBreadcrumb({ '@id': '#subbreadcrumb', 'itemListElement': [ { name: 'Sub breadcrumb link', item: '/blog/test' }, ], }) ``` ```json { "@id": "https://example.com/#subbreadcrumb", "@type": "BreadcrumbList" } ``` ### Type Transformer Providing a string of `@type` will be augmented with the default type. This is to allow fallbacks when the specific `@type` is not supported by Google. ```ts import { defineWebPage } from '@unhead/schema-org/@framework' defineWebPage({ '@type': 'FAQPage', }) ``` ```json { "@type": [ "WebPage", "FAQPage" ] } ``` ### Date Transformer Any date can be provided as a string or a js `Date` object. When a `Date` object is provided it will be transformed to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. ```ts import { defineWebPage } from '@unhead/schema-org/@framework' defineWebPage({ datePublished: new Date(2022, 1, 10, 0, 0, 0), }) ``` ```json { "datePublished": "2022-01-10T00:00:0+00:00" } ``` ## Third Party Validators To confirm the schema generated is valid, you should run it through both and .