Validate Plugin
ValidatePlugin checks the resolved tag set during rendering. Unlike source lint, it can report cross-tag conflicts, rendered byte budgets, and tags missing from the final output. The CLI uses the same rules when validating rendered HTML.
When to use it
- Development: register the plugin in dev to get live warnings in the console as you change tags.
- CI (via the CLI
validate-html/validate-urlcommands): the CLI loadsValidatePluginover your prerendered output or a live URL and exits non-zero on issues.
Register the plugin during development. Its heuristic checks add work to each render and are not intended for production traffic.
Usage
import { createHead } from 'unhead/client'
import { ValidatePlugin } from 'unhead/plugins'
const head = createHead({
plugins: [
ValidatePlugin(),
],
})
By default, every rule reports through console.warn with the source file and line of the useHead call that pushed the offending tag.
Options
ValidatePlugin({
// Override the per-rule severity. Accepts 'warn' | 'info' | 'off'
// or, for the rules below, a tuple of [severity, options].
rules: {
'missing-description': 'off',
'too-many-preloads': ['warn', { max: 10 }],
'too-many-prefetches': ['info', { max: 100 }],
'inline-style-size': ['info', { maxKB: 20 }],
},
// Replace the default console.warn dispatch.
onReport(rules) {
for (const r of rules)
myLogger.warn(r.id, r.message, r.source)
},
})
The optional root setting shortens captured source locations relative to an absolute project path. Supply it through build-time configuration; browser code does not have Node's process.cwd().
Configurable rules
A small set of rules accept a [severity, options] tuple to tune their thresholds:
| Rule | Option | Default |
|---|---|---|
charset-not-early | maxPosition | 3 |
inline-script-size | maxKB | 2 |
inline-style-size | maxKB | 14 |
meta-beyond-1mb | maxBytes | 1_048_576 |
too-many-fetchpriority-high | max | 2 |
too-many-preloads | max | 6 |
too-many-prefetches | max | 50 |
too-many-preconnects | max | 4 |
The too-many-prefetches default is an advisory guardrail for speculative bandwidth and cache use, not a browser or standards limit.
Rule IDs
Every rule has a stable string ID. The ESLint plugin uses the same IDs for equivalent source-level checks. The full list is exported as a runtime array:
import { VALIDATION_RULE_IDS } from 'unhead/validate'
console.log(VALIDATION_RULE_IDS) // ['canonical-og-url-mismatch', 'charset-not-early', ...]
unhead/validate also exports the KNOWN_META_NAMES, KNOWN_META_PROPERTIES, and URL_META_KEYS allowlists used for typo detection. These exports are available to other tooling.
deprecated-twitter-meta reports non-Slack twitter:* metadata and recommends Open Graph metadata. The Slack unfurl fields twitter:label1, twitter:label2, twitter:data1, and twitter:data2 are excluded.
Integration with DevTools
When the Unhead Vite plugin is active, reports from ValidatePlugin appear in the DevTools Tags and Audit panels. Each row links to the file and line that pushed the tag through Vite's open-in-editor endpoint.