Head
Environment: server.
Cumulative: true
.
Provided by: vike-react
/vike-vue
/vike-solid
.
You need
vike-react
/vike-vue
/vike-solid
to be able to use this setting.
The +Head
setting allows you to add <head>
tags to your pages.
See Guides >
<head>
tags for a general introduction about<head>
tags.
Common use cases:
// /pages/+Head.js
// Environment: server
import previewImage from './previewImage.jpg'
import favicon from './favicon.png'
import iconMobile from './iconMobile.png'
export function Head() {
return <>
{/* Icon shown in the browser tab (aka favicon) */
<link rel="icon" href={favicon} type="image/svg+xml">
{/* Icon shown on mobile homescreens (PWA) */
<link rel="apple-touch-icon" href={iconMobile} type="image/svg+xml">
{/* Add script tag */}
<script type="text/javascript" src="https://example.com/some-script.js"></script>
{/* Image shown when sharing on social sites (Twitter, WhatsApp, ...) */}
<meta property="og:image" content={previewImage}>
{/* More Open Graph tags */}
<meta property="og:type" content="website">
<meta property="article:author" content="https://example.com/author">
{/* Settings for search engine crawlers */}
<meta name="robots" content="index, follow">
{/* PWA settings */}
<meta name="theme-color" content="#00f">
<link rel="manifest" href="/manifest.webmanifest">
{/* CSP setting */}
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
</>
}
The
+Head
setting only applies to the HTML of the first page the user visits.As explained at Only HTML, you should use
+Head
only for<head>
tags that are either:
- global (e.g. favicon or PWA settings that don't change between pages), or
- intended for crawlers (e.g. SEO or social sharing tags).
You cannot use
+Head
for per-page tags intended for the user's browser such as<title>
(use+title
instead).
Only HTML
Only applies to the first page's HTML
The +Head
component is only rendered for the HTML of the first page the user visits: the tags set by +Head
aren't updated upon client-side page navigation.
Limitation
The most notable limitation is that the +Head
setting cannot be used to set the value of the <title>
tag, because its value won't update when navigating to a page with a different title.
See the example below for a more detailed explanation.
Instead use the +title
setting.
For use cases where the
+Head
setting cannot be used, Vike offers tailored settings that update upon client-side navigation.
Only a small limitation
This may seem like a major limitation but it actually isn't: you can use the +Head
setting for the vast majority of use cases.
You can use +Head
for setting <head>
tags are read by HTML crawlers:
- Tags for social sites (Twitter, Instagram, ...) such as
<meta property="og:image">
(the preview image upon URL sharing).Social site bots navigate your website only by using HTML requests: they don't execute client-side JavaScript and don't do client-side navigation.
- Tags for SEO such as
<meta name="description">
.While Google can do client-side navigation, it still discovers
<head>
tags by using its HTML crawler.
You can use +Head
for setting <head>
tags that are global (they have the same value for all pages):
- Favicon.
Assuming all your pages share the same favicon (
<link rel="icon">
), there isn't any need to update the favicon upon client-side navigation. - PWA settings.
PWA settings are global and there isn't any need to update them upon client-side navigation.
<script>
Assuming the script applies to all your pages.
Example
The following example showcases that using +Head
for setting <title>
doesn't work, while it does work for setting <meta name="description">
.
// /pages/index/+Head.jsx
// Environment: server
function Head() {
return <>
<title>AwesomeRockets</title>
<meta name="description" content="The rocket company.">
</>
}
// /pages/about/+Head.jsx
// Environment: server
function Head() {
return <>
<title>About us</title>
<meta name="description" content="We deliver payload to space.">
</>
}
If the first URL the user visits is /
then the rendered HTML is:
<!DOCTYPE html>
<html>
<head>
<title>AwesomeRockets</title>
<meta name="description" content="The rocket company.">
</head>
</html>
If the user then clicks on a link <a href="/about">About us</a>
, then Vike does client-side navigation and the page's title isn't updated: the browser sill shows Welcome
even though the URL is now /about
. That's because the HTML isn't used upon client-side navigation (DOM manipulations are made instead) while +Head
is only used when generating HTML.
The
+Head
component is only loaded on the server-side and only used when rendering HTML of the first page by design.
This isn't an issue for the <meta name="description">
tag because it's intended for search engines bots which
crawl your website using HTML.
Cumulative
The +Head
setting is cumulative. For example:
// /pages/+Head.js
// Environment: server
import favicon from './favicon.png'
// Applies to all pages (cannot be overridden)
export const Head = () =>
// All pages share the same favicon
<link rel="icon" href={favicon} type="image/svg+xml">
// /pages/about-us/+Head.js
// Environment: server
import previewImage from './previewImage.jpg'
export const Head = () =>
// Both the favicon above and this tag applies to /pages/about-us/+Page.js
<meta property="og:image" content={previewImage}>
To apply different +Head
settings to different pages:
// /pages/(marketing)/+Head.js
// Environment: server
import favicon from './favicon.png'
// Applies to all marketing pages
export const Head = () => <link rel="icon" href={favicon} type="image/svg+xml">
// /pages/admin/+Head.js
// Environment: server
import favicon from './favicon.png'
// Applies to all admin pages
export const Head = () => <link rel="icon" href={favicon} type="image/svg+xml">
If you have a need for overriding, then add a comment at: #1692 - Add
override
anddefault
options for cumulative configs
How to inject raw HTML?
You can inject any arbitrary HTML string to the page's <head>
. Examples using:
⚠️Be cautious about the security risk called XSS injections.
React
You can use React's dangerouslySetInnerHTML
to add raw HTML, for example:
import React from 'react'
import { Head } from 'vike-react/Head'
function Image({ src, author }) {
return (
<>
<img src={src} />
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
'@context': 'https://schema.org/',
contentUrl: { src },
creator: {
'@type': 'Person',
name: author
}
})
}}
></script>
</Head>
</>
)
}
Vue
You can use innerHTML
to add raw HTML, for example:
<template>
<img :src v-bind="otherAttrs" />
</template>
<script setup>
import { useAttrs, h } from 'vue'
import { useConfig } from 'vike-vue/useConfig'
const { src, author, ...otherAttrs } = useAttrs()
const config = useConfig()
config({
Head: h('script', {
type: 'application/ld+json',
innerHTML: JSON.stringify({
'@context': 'https://schema.org/',
contentUrl: { src },
creator: {
'@type': 'Person',
name: author
}
})
})
})
</script>
Solid
You can use innerHTML
to add raw HTML, for example:
import { Head } from "vike-solid/Head"
function Image({ src, author }) {
return (
<>
<img src={src} />
<Head>
<script
type="application/ld+json"
innerHTML={JSON.stringify({
"@context": "https://schema.org/",
contentUrl: { src },
creator: {
"@type": "Person",
name: author
}
})}
></script>
</Head>
</>
)
}