<head>
tags without vike-{react,vue,solid}
If you don't use vike-react
/vike-vue
/vike-solid
, then you have direct control over <head>
tags in your onRenderHtml()
hook.
If you use
vike-react
/vike-vue
/vike-solid
, then see Guides ><head>
tags.
// /renderer/+onRenderHtml.js
// Environment: server
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import { renderToHtml } from 'some-ui-framework'
export { onRenderHtml }
async function onRenderHtml(pageContext) {
return escapeInject`<html>
<head>
<title>SpaceX</title>
<meta name="description" content="We deliver payload to space.">
</head>
<body>
<div id="root">
${dangerouslySkipEscape(await renderToHtml(pageContext.Page))}
</div>
</body>
</html>`
}
By page
To define <head>
tags on page-by-page basis, we recommend creating new settings, for example title
and description
as shown at API > meta
> Example: title
and description
.
By component
To define <head>
tags by any UI component:
- Add
'headProps'
topassToClient
. - Use
usePageContext()
so thatpageContext.headProps
can be accessed and modified by any component.
For example:
// /renderer/+onRenderHtml.js
// Environment: server
export { onRenderHtml }
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import renderToHtml from 'some-ui-framework'
async function onRenderHtml(pageContext) {
// We use our UI framework to pass `pageContext.headProps` to all components
// of our component tree. (E.g. React Context or Vue's `app.config.globalProperties`.)
const pageHtml = await renderToHtml(
<ContextProvider headProps={pageContext.headProps} >
<Page />
</ContextProvider>
)
// 1. One of our UI component modified pageContext.headProps while rendering components.
// 2. We now render `headProps` to HTML meta tags.
return escapeInject`<html>
<head>
<title>${pageContext.headProps.title}</title>
<meta name="description" content="${pageContext.headProps.description}">
</head>
<body>
<div id="app">
${dangerouslySkipEscape(pageHtml)}
</div>
</body>
</html>`
}
// SomeComponent.js
// Inside a UI component
const pageContext = usePageContext()
const { headProps } = pageContext
headProps.title = 'I was set by some component.'
headProps.description = 'Me too.'
Client Routing
If you use Client Routing, make sure to update document.title
upon page navigation:
// /renderer/+config.js
// Environment: config
export default {
// Make pageContext.headProps available on the client-side.
passToClient: ['headProps']
}
// /renderer/+onRenderClient.js
// Environment: client
export { onRenderClient }
async function onRenderClient(pageContext) {
if (!pageContext.isHydration) {
// Client-side navigation — we update the page's title
document.title = pageContext.headProps.title
}
// ...
}
Libraries
You can also use libraries such as @vueuse/head or react-helmet.
But we recommend using such library only if you have a rationale as the aforementioned solutions are simpler.
Head libraries already sanitize the HTML <head>
, this means you can skip escapeInject
and wrap the overall result with dangerouslySkipEscape()
.
// /renderer/+onRenderHtml.js
// Environment: server
export { onRenderHtml }
import { dangerouslySkipEscape } from 'vike/server'
import { renderToHtml } from 'some-ui-framework'
async function onRenderHtml(pageContext) {
return dangerouslySkipEscape(await renderToHtml(pageContext.Page))
}