Skip to content
forked from vueuse/head

Document <head> manager for Vue. SSR ready.

License

Notifications You must be signed in to change notification settings

vetruvet/vueuse-head

 
 

Repository files navigation

@vueuse/head

NPM version NPM Downloads
GitHub stars

A Vue composition API to manage your document head.


Created by egoist, maintained by harlan-zw
💛 Support ongoing development by sponsoring us.
Follow 🐦 @harlan_zw for updates • Join Discord for support

Features

  • ✨ Best practice head with deduping and default ordering
  • 🤖 SSR ready
  • 🔨 Deeply reactive with computed getter support
  • 🌳 Fully typed with augmentation support (powered by zhead)

Installation

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

Requires vue >= v3 or >=2.7

For instructions on setting up @vueuse/head as an integration, see integration.

API

useHead(head: MaybeComputedRef<HeadObject>)

Used to modify the head of the document. You can call this function in any page or component.

All values are reactive and support ref and computed getter syntax.

To provide inner content you should use the textContent attribute (previously children which is deprecated).

Note: All values provided to useHead will be encoded to avoid XSS injection. If you need to insert raw data use useHeadRaw.

Example

const myPage = ref({
  description: 'This is my page',
})
const title = ref('title')
useHead({
  // ref syntax
  title,
  meta: [
    // computer getter syntax  
    { name: 'description', content: () => myPage.value.description },
  ],
  style: [
    { type: 'text/css', textContent: 'body { background: red; }' },
  ],
  script: [
    // primitive values are also fine
    { 
      src: 'https://example.com/script.js',
      defer: true
    },
  ],
})

Types

You can check @zhead/schema for full types.

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

useHeadRaw(head: MaybeComputedRef<HeadObject>)

Has the same functionality as useHead but does not encode values. This is useful for inserting raw data such as scripts and attribute events.

When inserting raw inner content you should use innerHTML.

useHeadRaw({
  bodyAttrs: {
    onfocus: 'alert("hello")',
  },
  script: [
    {
      innerHTML: 'alert("hello world")',
    },
  ],
})

Deduping

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",
    },
  ],
})

Body Tags

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

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

Text Content

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

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.

Integration

For integrating @vueuse/head with a framework.

Examples

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, 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: () => siteData.title,
      meta: [
        {
          name: `description`,
          content: () => 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.

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

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 99.7%
  • JavaScript 0.3%