Unhead wraps your document template, improving reactive SSR JavaScript framework SEO and performance.
useHead({
title: 'Hello World',
titleTemplate: '%s %separator My App',
})
// Hello World - My App
useHead({
script: [{
src: '/script.js',
onload: () => alert('woo'),
}],
})
useHead({
bodyAttrs: {
// use strings
style: 'background-color: #343434',
// arrays
class: ['dark', 'overflow'],
},
htmlAttrs: {
// objects
style: {
backgroundColor: 'white',
color: 'black',
},
// computed boolean objects
class: {
dark: () => Date.now() % 2 === 0,
},
},
})
useHead({
title: 'Subscribe now!',
htmlAttrs: {
class: { dark: true, light: false }
},
bodyAttrs: {
'style': { overflow: 'hidden' },
'data-modal': true,
},
link: [{
rel: 'preload',
href: 'https://3p.com/subscribe.js',
as: 'script',
}],
})
<!DOCTYPE html>
<html class="light">
<head>
<title>Hello World</title>
</head>
<body>
<!-- Your app -->
</body>
</html>
Was it <meta property
or <meta name
? Who can remember, just use useSeoMeta()
.
useSeoMeta({
ogType: 'article',
author: 'Harlan Wilton',
articleAuthor: ['Harlan Wilton'],
articlePublishedTime: '2024-01-01',
articleModifiedTime: '2024-01-01',
twitterData1: 'Harlan Wilton',
twitterLabel1: 'Author',
twitterData2: '10 min',
twitterLabel2: 'Read Time',
})
Rich result optimized Schema.org graphs without the application/ld+json
.
useSchemaOrg([
definePerson({
name: 'Harlan Wilton',
sameAs: [
'https://github.com/harlan-zw',
],
url: 'https://harlanzw.com',
}),
defineArticle({
headline: 'Hello World',
datePublished: '2024-01-01',
}),
])
Unhead ships with a default head tag order that is optimized for SEO and performance.
<head>
<script defer src="defer-script.js"></script>
<script src="sync-script.js"></script>
<style>.sync-style { color: red }</style>
<link rel="modulepreload" href="modulepreload.js">
<script src="async-script.js" async></script>
<link rel="preload" href="preload.js">
<link rel="stylesheet" href="sync-styles.css">
<title>title</title>
<link rel="preconnect" href="https://example.com">
<link rel="dns-prefetch" href="https://example.com">
<link rel="prefetch" href="https://example.com">
<link rel="prerender" href="https://example.com">
<meta name="description" content="description">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<script>
for full stack javascriptBetter developer experience, performance and privacy.
const script = useScript({
src: 'https://js.cdn/tracker.js',
}, {
trigger: useOnIdle()
})
script.onError((error) => { /* uh oh */ })
// proxy function calls for when the script is loaded
script.proxy.track('foo')
// or just use onLoaded
script.onLoaded((api) => {
api.track('bar')
})
<link fetchpriority="low" as="script" crossorigin="anonymous" referrerpolicy="no-referrer" href="https://js.cdn/tracker.js" rel="preload">
<script data-onload="" data-onerror="" defer="" fetchpriority="low" crossorigin="anonymous" referrerpolicy="no-referrer" src="https://js.cdn/tracker.js"></script>
// Unhead tags are built to tree-shake, it just works
if (import.meta.server) {
useHead({
meta: [{
name: 'description',
content: 'Hello World',
}],
script: [{
innerHTML: 'console.log("Hello World")',
}],
})
}
Unhead was started at the end of 2022 and has received continuous bug fixes and feature improvements from the community.
Unhead is used and trusted by thousands of developers and companies around the world.
Unhead is completely free and open-source due to the generous support of the community.