zhead
Typed utilities for defining, validating and building best-practice document <head>'s.
Status: Pre-release Please report any issues Made possible by my Sponsor Program Follow me @harlan_zw |
Features
- 🇹 Fully typed document <head> with inline doc
-
💎 Zod powered schema parsing and validation -
🔨 Vue bindings for deep reactiveRef
andComputed
support, useHead compatible -
🌳 Composable, tree-shakable and tiny (< 1kb, see export-size-report)
Numerous utilities
-
🧙 Resolve flat meta tags (100+ typed)unpackMeta
-
✨ SEO inferring to generate minimal tags with maximum SEObuildSeoHead
-
✍️ Output to HTMLgenerateHtml
Installation
npm install --save-dev zhead
# Using yarn
yarn add --dev zhead
Sub-packages
TypeScript
Typescript base schema for document <head>. Only ships types for easy access to type augmentation.
Validation and parsing
Zod schema for validating and parsing head tags.
Framework bindings
Vue bindings for handling deep reactive Ref
and Computed
head tags.
API
defineHead
Use this decorator for a simple fully-typed head schema.
import { defineHead } from 'zhead'
const head = defineHead({
title: 'My Page',
})
// {
// title: 'My Page',
// }
unpackMeta
Define your meta tags in a simple object with full type-safety.
import { defineHead, resolveMetaFlat } from 'zhead'
const meta = unpackMeta({
contentSecurityPolicy: {
contentSrc: 'none'
},
viewport: {
width: 'device-width',
initialScale: 1,
userScalable: 'yes',
}
})
// [
// { 'http-equiv': 'content-security-policy', content: 'content-src none' },
// { 'name': 'viewport', content: 'width=device-width, user-scalable=yes, initial-scale=1' }
// ]
packMeta
Turn array meta tags into a flat packed object.
import { defineHead, resolveMetaFlat } from 'zhead'
const meta = packMeta([
{
'content': 'default-src \'self\' https://example.com; content-src none',
'http-equiv': 'content-security-policy',
},
{
name: 'description',
content: 'desc',
},
{
content: '1234567890',
property: 'fb:app_id',
},
])
// {
// "description": "desc",
// "fbAppId": "1234567890",
// "contentSecurityPolicy": "default-src 'self' https://example.com; content-src none"
// }
resolveSeoHead
Generate a minimal SEO head with maximum SEO.
Internally this function uses the withDefaults
and inferSocialShare
utilities.
- Adds utf-8 charset
- Sets default best practice viewport
- Infers social share tags from
title
anddescription
- Sets twitter card to
summary_large_image
- Sets robots best practice
import { resolveSeoHead, resolveMetaFlat } from 'zhead'
const head = resolveSeoHead({
title: 'Learn about zHead - zHead',
description: 'Describing the basic usage of zHead.',
})
// {
// "title": "My Title",
// "meta": [
// {
// "content": "Some description",
// "name": "description",
// },
// {
// "charset": "utf-8",
// },
// {
// "content": "initial-scale=1, width=device-width",
// "name": "viewport",
// },
// {
// "content": "My Title",
// "property": "og:title",
// },
// {
// "content": "Some description",
// "property": "og:description",
// },
// {
// "content": "max-snippet:-1, max-image-preview:large, max-video-preview:-1",
// "name": "robots",
// },
// ],
// }
Generate API
generateHtml
import { generateHtml } from 'zhead'
const html = generateHtml({
title: 'test',
script: [
{ src: 'https://example.com/script.js' },
],
meta: [
{ name: 'description', content: 'test' },
]
})
// <title>test</title>
// <meta content="test" name="description">
// <script src="https://example.com/script.js"></script>
generateTags
import { generateTags } from 'zhead'
const tags = generateTags({
title: 'test',
script: [
{ src: 'https://example.com/script.js' },
],
meta: [
{ name: 'description', content: 'test' },
]
})
// [
// {
// "props": {
// "children": "test",
// },
// "tag": "title",
// },
// {
// "props": {
// "content": "test",
// "name": "description",
// },
// "tag": "meta",
// },
// {
// "props": {
// "src": "https://example.com/script.js",
// },
// "tag": "script",
// },
// ]
Sponsors
License
MIT License © 2022-PRESENT Harlan Wilton