@vueuse/head
A Vue composition API to manage your document head.
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
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({
title,
meta: [
{ name: 'description', content: () => myPage.value.description },
],
style: [
{ type: 'text/css', textContent: 'body { background: red; }' },
],
script: [
{
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
:warning: 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: [
{
src: "/very-important-script.js",
renderPriority: 1
},
],
})
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: ,
<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)
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)
export interface HTMLResult {
readonly headTags: string
readonly htmlAttrs: string
readonly bodyAttrs: string
readonly bodyTags: string
}
Render the head manager instance to HTML tags in string form.
License
MIT © EGOIST