In implementing Schema.org, we mostly care about Rich Results from Google as they can help improve the visibility of your content in search results.
For example:
Providing structured data can also help search engines understand your content better but in most cases, is unnecessary.
<!-- This is what Schema.org looks like -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "When Schema.org Actually Matters",
"author": "Your Name"
}
</script>
In Vue the head manager we use is called Unhead.
Using it we can either use useHead() to create Schema.org, however it's recommended to use the useSchemaOrg() composable as it provides type safety and creates Schema.org graphs.
useSchemaOrg([
defineArticle({
title: 'Schema.org in Vue',
description: 'Schema.org can help search engines understand your content better, but is it worth the effort? Learn when to use it and when to skip it in Vue applications.',
})
])
useHead({
scripts: [
{
type: 'application/ld+json',
innerHTML: {
'@context': 'https://schema.org',
'@type': 'Article',
'headline': 'Schema.org in Vue',
'author': 'Your Name'
}
}
],
})
All we need to do is add the dependency to our project. For full install instructions see the Install Unhead Schema.org documentation.
pnpm add -D @unhead/schema-org
The useSchemaOrg() composable supports any arbitrary schema.
useSchemaOrg([
// passing json is fine
{
'@context': 'https://schema.org',
'@type': 'Article',
'headline': 'Schema.org in Vue',
'author': 'Your Name'
}
])
It is best used when combined with the numerous defineX() helpers that provide a type-safe way to define schema
which aligns to Google's Structured Data Guidelines.
For example:
See the Unhead Schema.org documentation for more details.
useSchemaOrg()The useSchemaOrg() composable accepts any reactive data you can throw at it.
const article = ref({
title: 'Schema.org in Vue',
description: 'Schema.org can help search engines understand your content better, but is it worth the effort? Learn when to use it and when to skip it in Vue applications.'
})
useSchemaOrg([
defineArticle({
// computed getter
title: () => article.value.title,
description: () => article.value.description,
})
])
For generic pages we can provide a minimal configuration that works across all pages.
<script lang="ts" setup>
import { defineOrganization, defineWebPage, defineWebSite, useSchemaOrg } from '@unhead/schema-org/vue'
// we can remove a lot of boilerplate from Schema.org by providing template params
const route = useRoute()
useHead({
templateParams: {
schemaOrg: {
host: 'https://mysite.com',
path: route.path,
inLanguage: 'en',
}
}
})
useSchemaOrg([
// much of the data will be inferred such as the title, description and all URLs
defineWebPage(),
defineWebSite({
name: 'My Site',
description: 'My Site is a collection of hand-crafted resources to help you build better.',
}),
// choose an identity, either with definePerson or an defineOrganization
defineOrganization({
name: 'My Site',
})
])
</script>
For a personal blog, we can provide more detailed information about the author.
<script lang="ts" setup>
import { definePerson, defineWebPage, defineWebSite, useSchemaOrg } from '@unhead/schema-org/vue'
useSchemaOrg([
defineWebPage(),
defineWebSite({
name: 'My Blog',
description: 'A blog about my life and experiences.',
}),
definePerson({
name: 'Your Name',
url: 'https://your-blog.com',
image: 'https://your-blog.com/avatar.jpg',
sameAs: [
'https://twitter.com/your-twitter',
]
}),
])
</script>
For a blog, we can provide more detailed information about the author and the blog.
As Vue is hierarchical, we don't need to define the WebSite and WebPage nodes in every component if they're defined in the layout.
<script lang="ts" setup>
import { defineArticle, useSchemaOrg } from '@unhead/schema-org/vue'
useSchemaOrg([
defineArticle({
// title and description will be inferred from the head tags
image: '/photos/16x9/photo.jpg',
datePublished: new Date(2020, 1, 1),
dateModified: new Date(2020, 1, 1),
})
])
</script>
If you're using Nuxt, check out Nuxt SEO which handles much of this automatically.