Getting Started

How It Works

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 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.

Site / Page Level Config

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 <title> 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> data:

  • inLanguage - <html lang="en"> (en)
  • name - <title>test</title> (test)
  • description - <meta name="description" content="test"> (test)
  • url - <link rel="canonical" href="https://example.com/my-page"> (https://example.com)
  • image - <meta property="og:image" content="https://example.com/image.jpg"> (https://example.com/image.jpg)

Otherwise, they will come from your Schema.org Params.

Deduping Nodes

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.

Transformers

There's numerous resolvers available to help minimise the work in maintaining and developing Schema.

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.

defineComment({
  text: 'This is really cool!',
  author: {
    name: 'Harlan Wilton',
    url: '/user/harlan-wilton',
  }
})
[
  {
    "@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 and added as a root node and an applicable link to the @id will be added.

defineWebPage({
  image: '/my-image.png',
})
{
  "@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.

defineBreadcrumb({
  '@id': '#subbreadcrumb',
  'itemListElement': [
    { name: 'Sub breadcrumb link', item: '/blog/test' },
  ],
})
{
  "@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.

defineWebPage({
  '@type': 'FAQPage',
})
{
  "@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 format.

defineWebPage({
  datePublished: new Date(2022, 1, 10, 0, 0, 0),
})
{
  "datePublished": "2022-01-10T00:00:0+00:00"
}