Skip to content
On this page

Install Schema.org on Nuxt

Install the module to start using Schema.org with Nuxt v3.

⚠️ The module does not currently support Nuxt v2 or bridge. May be implemented soon.

Open in StackBlitz

Install

# NPM
npm install -D nuxt-schema-org
# or Yarn
yarn add -D nuxt-schema-org
# or PNPM
pnpm add -D nuxt-schema-org

Setup Module

1. Add Module

Add the module to your Nuxt config.

nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    'nuxt-schema-org',
  ],
})

All composable utilities and components are automatically imported for you thanks to Nuxt auto import. See Disable Auto Imports if you'd like to opt-out.

2. Configure the module

To server-side render correctly and make appropriate Schema adjustments, the module requires the following:

  • canonicalHost string

    The canonical host of your site. You can conditionally swap this depending on the environment, but it's not needed, simply putting the production host is enough.

nuxt.config.ts
export default defineNuxtConfig({
  schemaOrg: {
    // set to your production domain  
    canonicalHost: 'https://example.com',
  },
})

Check the global configuration if you'd like to make further global configurations.

3. Configure Global Schema

To get all your pages up and running with Schema, you can make use schema inheritance and define Schema in your app.vue file.

This allows all pages to inherit these Schemas, without them having to explicitly define them.

a. Composition API

app.vue
<script lang="ts" setup>
useSchemaOrg([
   // https://vue-schema-org.netlify.app/guide/guides/identity.html
  // @todo select appropriate identity
  // https://vue-schema-org.netlify.app/schema/website.html
  defineWebSite({
    name: 'My Awesome Website',
  }),
  // https://vue-schema-org.netlify.app/schema/webpage.html
  defineWebPagePartial(),
])
</script>

b. Component API

app.vue
<template>
  <!-- @todo choose an identity: https://vue-schema-org.netlify.app/guide/guides/identity.html -->
  <SchemaOrgWebSite name="My Awesome Website" />
  <SchemaOrgWebPage />
  <RouterView />
</template>

4. Optional: WebPage Configuration

With the global schema provided in your root component, every page will generate a WebPage entry.

In most cases you won't need to explicitly call defineWebPage again as inferences will be made based on your pages meta.

See the Nuxt meta-tags documentation on the best way to do this.

a. useHead

Only supports the following inferences:

  • title document.title
  • description meta[name="description"]
  • image meta[property="og:image"]
<script setup>
useHead({
  title: 'Hello World',
  meta: [ 
    { name: 'description',  content: 'This is a description' },
    { property: 'og:image',  content: 'https://example.com/preview.png' },
  ],
});
</script>

b. definePageMeta
  • Supports all inferences
  • Not ideal for dynamic routes
<script setup>
definePageMeta({
  title: 'Hello World',
  description: 'This is a description',
  dateModified: new Date(2020, 1, 3),
  datePublished: new Date(2020, 1, 1),
  image: '/images/logo.png',
});
</script>

c. defineWebPage or SchemaOrgWebPage

If you'd like full control over the WebPage data, you can define it again on any of the pages.

<script setup>
useSchemaOrg(
  defineWebPage({
    name: 'Hello World',
    description: 'This is a description',
    dateModified: new Date(2020, 1, 3),
    datePublished: new Date(2020, 1, 1),
    image: '/images/logo.png',
  })
)
</script>
<template>
  <SchemaOrgWebPage name="Hello World" />
</template>

Next Steps

Your site is now serving basic Schema.org for all pages, congrats! 🎉

The next steps are:

  1. Choose an Identity
  2. Get an understanding of How it works
  3. Then feel free to add some custom recipes:

Optional: Disable Auto Imports

If you'd like to disable auto-imports for whatever reason, you can use the config.

nuxt.config.ts
export default defineNuxtConfig({
  schemaOrg: {
    /**
     * Whether composables will be automatically imported for you.
     */
    autoImportComposables: false,
    /**
     * Whether components will be automatically imported for you.
     */
    autoImportComponents: false,
  },
})