Skip to content

Document <head> manager for Vue 3. SSR ready.

License

Notifications You must be signed in to change notification settings

huang-julien/vueuse-head

 
 

Repository files navigation

@vueuse/head

npm version npm downloads

Document head manager for Vue 3.

@vueuse/head is a Vue composition API that helps you manage <title>, <meta> and other elements inside document head, it has no dependencies and we always try to keep it as slim as possible.

💛 Support the ongoing development of this project by becoming a GitHub Sponsor.

Installation

npm i @vueuse/head
# Or Yarn
yarn add @vueuse/head

Usage

Register the Vue plugin:

import { createApp } from "vue"
import { createHead } from "@vueuse/head"

const app = createApp()
const head = createHead()

app.use(head)

app.mount("#app")

Manage head with the composition API useHead in your component:

<script>
import { defineComponent, computed, reactive } from "vue"
import { useHead } from "@vueuse/head"

export default defineComponent({
  setup() {
    const siteData = reactive({
      title: `My website`,
      description: `My beautiful website`,
    })

    useHead({
      // Can be static or computed
      title: computed(() => siteData.title),
      meta: [
        {
          name: `description`,
          content: computed(() => siteData.description),
        },
      ],
    })
  },
})
</script>

Server-side rendering

import { renderToString } from "@vue/server-renderer"
import { renderHeadToString } from "@vueuse/head"

const appHTML = await renderToString(yourVueApp)

// `head` is created from `createHead()`
const { headTags, htmlAttrs, bodyAttrs, bodyTags } = renderHeadToString(head)

const finalHTML = `
<html${htmlAttrs}>

  <head>
    ${headTags}
  </head>

  <body${bodyAttrs}>
    <div id="app">${appHTML}</div>
    ${bodyTags}
  </body>

</html>
`

API

createHead(head?: HeadObject | Ref<HeadObject>)

Create the head manager instance.

useHead(head: HeadObject | Ref<HeadObject>)

interface HeadObject {
  title?: MaybeRef<string>
  titleTemplate?: MaybeRef<string> | ((title?: string) => string)
  meta?: MaybeRef<HeadAttrs[]>
  link?: MaybeRef<HeadAttrs[]>
  base?: MaybeRef<HeadAttrs>
  style?: MaybeRef<HeadAttrs[]>
  script?: MaybeRef<HeadAttrs[]>
  noscript?: MaybeRef<HeadAttrs[]>
  htmlAttrs?: MaybeRef<HeadAttrs>
  bodyAttrs?: MaybeRef<HeadAttrs>
}

interface HeadAttrs {
  [attrName: string]: any
}

For meta tags, we use name and property to prevent duplicated tags, you can instead use the key attribute if the same name or property is allowed:

useHead({
  meta: [
    {
      property: "og:locale:alternate",
      content: "zh",
      key: "zh",
    },
    {
      property: "og:locale:alternate",
      content: "en",
      key: "en",
    },
  ],
})

To render tags at the end of the <body>, set body: true in a HeadAttrs Object.

useHead({
  script: [
    {
      children: `console.log('Hello world!')`,
      body: true,
    },
  ],
})

To set the textContent of an element, use the children attribute:

useHead({
  style: [
    {
      children: `body {color: red}`,
    },
  ],
  noscript: [
    {
      children: `Javascript is required`,
    },
  ],
})

useHead also takes reactive object or ref as the argument, for example:

const head = reactive({ title: "Website Title" })
useHead(head)
const title = ref("Website Title")
useHead({ title })

Render Priority

⚠️ Experimental feature Only available when rendering SSR.

To set the render priority of a tag you can use the renderPriority attribute:

useHead({
  script: [
    {
      src: "/not-important-script.js",
    },
  ],
})

useHead({
  script: [
    // will render first
    {
      src: "/very-important-script.js",
      renderPriority: 1 // default is 10, so will be first
    },
  ],
})

The following special tags have default priorities:

  • -2 <meta charset ...>
  • -1 <base>
  • 0 <meta http-equiv="content-security-policy" ...>

All other tags have a default priority of 10: , <script>, , <style>, etc

<Head>

Besides useHead, you can also manipulate head tags using the <Head> component:

<script setup lang="ts">
import { Head } from "@vueuse/head"
</script>

<template>
  <Head>
    <title>Hello World</title>
    <base href="/base" />
    <html lang="en-US" class="theme-dark" />
  </Head>
</template>

Note that you need to use <html> and <body> to set htmlAttrs and bodyAttrs respectively, children for these two tags and self-closing tags like <meta>, <link> and <base> are also ignored.

renderHeadToString(head: Head)

  • Returns: HTMLResult
export interface HTMLResult {
  // Tags in `<head>`
  readonly headTags: string
  // Attributes for `<html>`
  readonly htmlAttrs: string
  // Attributes for `<body>`
  readonly bodyAttrs: string
  // Tags in `<body>`
  readonly bodyTags: string
}

Render the head manager instance to HTML tags in string form.

Sponsors

sponsors

License

MIT © EGOIST

About

Document <head> manager for Vue 3. SSR ready.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 100.0%