Index of every page on this site: llms.txt
TypeScript
Tooling

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-url commands): the CLI loads ValidatePlugin over 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:

RuleOptionDefault
charset-not-earlymaxPosition3
inline-script-sizemaxKB2
inline-style-sizemaxKB14
meta-beyond-1mbmaxBytes1_048_576
too-many-fetchpriority-highmax2
too-many-preloadsmax6
too-many-prefetchesmax50
too-many-preconnectsmax4

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.

Did this page help you?