Skip to content

chore(deps): update peerdependency @unhead/vue to v3 - #703

Closed
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-unhead-monorepo
Closed

chore(deps): update peerdependency @unhead/vue to v3#703
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-unhead-monorepo

Conversation

@renovate

@renovaterenovateBot commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

PackageChangeAgeConfidence
@unhead/vue (source)^2.0.3^3.1.0ageconfidence

Release Notes

unjs/unhead (@​unhead/vue)

v3.1.0

Compare Source

🛠️ Unhead CLI

To assist with migrations and overall DX a CLI has been introduced: @unhead/cli.

npx -y @​unhead/cli 

It lets you do the following:

 audit Lint your codebase for unhead misuse, type-narrowing issues, and SEO/perf foot-guns. migrate Apply autofixes forv2-to-v3 migration: rewrite deprecated props and wrap tag literalsin defineX helpers.
validate-html Run the runtime ValidatePlugin over prerendered HTML files (e.g. dist/, .output/, build/). validate-url Fetch a rendered URL and run unhead\'s SEO/perf validation rules over its <head>. 

For example, try running audit on your own project for hints on how to improve your SEO.

✔️ Unhead ESLint

Knowing that your useHead() and useSeoMeta() code is right while your coding is important. While type-narrowing solves many broken cases, we introduce an ESLint plugin to help catch anything that the typechecker can't catch.

These rules are shared from the runtime ValidatePlugin

# flat-config ESLint plugin with v2→v3 migration autofixes
npm i -D @&#8203;unhead/eslint-plugin
```ts[eslint.config.ts]import{configs}from'@&#8203;unhead/eslint-plugin'exportdefault[configs.recommended,]

🌊 Streaming SSR non-Vite support

The streaming plugin lived only at unhead/stream/vite previously, leaving non-Vite users with no way to wire the bootstrap. The plugin is now a bundler-agnostic unplugin factory with first-class webpack and Vite entries, and the framework packages compose it behind Unhead({ streaming: true }).

// vite.config.tsimport{Unhead}from'@&#8203;unhead/vue/vite'exportdefault{plugins: [vue(),Unhead({streaming: true})]}// webpack.config.tsimport{Unhead}from'@&#8203;unhead/vue/bundler'exportdefault{plugins: [...Unhead({streaming: true}).webpack()]}

Streaming also gains a nonce option (forwarded on every injected <script> for CSP support), a fixed async mode for production Vite builds (the IIFE is now emitted via this.emitFile() so the script src references a real hashed asset), a dev-mode warning when the client IIFE runs against an empty server queue, and a shared StreamingGlobal type so the server bootstrap, client, and injected IIFE agree on the shape of window.__unhead__. Default mode changed from async to inline for smaller TTFB.

Changelog

🚀 Features
🐞 Bug Fixes
View changes on GitHub

v3.0.5

Compare Source

🐞 Bug Fixes
View changes on GitHub

v3.0.4

Compare Source

🐞 Bug Fixes
View changes on GitHub

v3.0.3

Compare Source

🐞 Bug Fixes
View changes on GitHub

v3.0.2

Compare Source

🐞 Bug Fixes
View changes on GitHub

v3.0.1

Compare Source

🐞 Bug Fixes
View changes on GitHub

v3.0.0

Compare Source

Unhead v3 rebuilds the rendering engine from the ground up. The motivation: streaming SSR. Frameworks like Nuxt, SolidStart, and SvelteKit stream HTML to the browser as data loads, but head tags were still stuck in a request/response model, resolved once and never updated. To fix this properly, we had to make rendering synchronous, pluggable, and side-effect free. The result is a faster, smaller, and more capable head manager.

📣 Highlights

🌊 Streaming SSR

Head tags now update dynamically as suspense boundaries resolve during streaming. As each chunk streams to the browser, new <title>, <meta>, and <link> tags are pushed to a client-side queue and applied to the DOM. No waiting for the full page to load.

// entry-server.tsimport{createStreamableHead}from'@&#8203;unhead/vue/stream/server'const{ head, wrapStream }=createStreamableHead()app.use(head)// wraps the Vue stream, injecting head updates as chunks resolvereturnwrapStream(renderToWebStream(app),template)
// entry-client.tsimport{createStreamableHead}from'@&#8203;unhead/vue/stream/client'consthead=createStreamableHead()app.use(head)

Under the hood: a queue stub (window.__unhead__) collects head entries as they stream in before the main JS bundle loads. Once the client head instance initializes, it processes the queue and takes over. No entries are ever lost regardless of timing.

Streaming is supported for Vue, React, Solid.js, Svelte, and vanilla TypeScript. See PR #​537.

🛠️ Unified Vite Plugin + DevTools

A single @unhead/{framework}/vite plugin replaces the old manual composition of @unhead/addons + streaming plugin + framework glue. One import, one call, and you get tree-shaking, useSeoMetauseHead transform, inline minification, streaming SSR, dev-mode ValidatePlugin auto-injection, and Vite DevTools integration.

// vite.config.tsimport{Unhead}from'@&#8203;unhead/vue/vite'importvuefrom'@&#8203;vitejs/plugin-vue'exportdefaultdefineConfig({plugins: [vue(),Unhead()],})

The DevTools panel surfaces live head state during development: every useHead() / useSeoMeta() call with its source file and line number, resolved tags, SEO overview (title, description, canonical, Open Graph), useScript() load status, active plugins, template params, and warnings from the Validate plugin. Source tracing lets you click through from any tag back to the exact line that created it.

Available for Vue, React, Svelte, Solid, and vanilla via @unhead/bundler/vite (the renamed @unhead/addons package; the old name still works with a deprecation warning).

See PRs #​726, #​733, #​731.

🎯 useHead() Type Narrowing

useHead() now narrows types based on input. Link, script, and meta tags resolve to specific subtypes instead of a generic union, so you get precise autocomplete and type errors when something is wrong.

useHead({link: [// Narrows to StylesheetLink: requires href, offers media, integrity, etc.{rel: 'stylesheet',href: '/styles.css'},// Narrows to PreloadLink: requires as attribute{rel: 'preload',as: 'font',href: '/font.woff2',crossorigin: 'anonymous'},],script: [// Narrows to ModuleScript{src: '/app.mjs',type: 'module'},// Narrows to JsonLdScript{type: 'application/ld+json',innerHTML: '{}'},],})

See PRs #​627, #​665, #​729.

✅ ValidatePlugin

New optional ValidatePlugin that inspects resolved head output and warns about common mistakes: missing titles, duplicate meta tags, contradictory preload priorities, render-blocking scripts, late <meta charset>, too many fetchpriority="high" hints, preconnect without crossorigin, and more. Also includes v2 migration rules that detect deprecated property names (children, hid/vmid, body: true), missing TemplateParamsPlugin, and missing AliasSortingPlugin — all of which cause silent breakage on upgrade. Auto-injected in dev by the unified Vite plugin so warnings surface in the browser console without any manual setup. Fully tree-shakeable. Rules use ESLint-style flat config:

import{ValidatePlugin}from'unhead/plugins'createHead({plugins: [ValidatePlugin({rules: {'missing-description': 'off',}})]})

See PRs #​690, #​691, #​716, #​722, #​725, #​732.

🔗 Canonical Plugin

New built-in CanonicalPlugin that auto-generates <link rel="canonical"> tags and resolves relative URLs to absolute in og:image, twitter:image, and og:url. Includes query parameter filtering (strips tracking params like utm_source, fbclid, gclid by default), trailing slash normalization, and automatic hash fragment stripping. Essential for SEO and social sharing.

import{CanonicalPlugin}from'unhead/plugins'createHead({plugins: [CanonicalPlugin({canonicalHost: 'https://mysite.com',trailingSlash: true,queryWhitelist: ['page','sort'],})]})

See PRs #​492, #​713.

🗜️ MinifyPlugin

New optional MinifyPlugin that minifies inline <script> and <style> tag content during SSR. Uses lightweight pure-JS minifiers with zero native dependencies, safe for edge and serverless runtimes. A companion build-time transform (MinifyTransform in @unhead/bundler) pre-minifies static innerHTML literals at compile time. Standalone utilities (minifyJS, minifyCSS, minifyJSON) are also available via unhead/minify.

import{MinifyPlugin}from'unhead/plugins'createHead({plugins: [MinifyPlugin()]})

See PR #​705.

📦 Performance

Buildv3 sizev2 sizeDelta gz
client1025411513-534 (-11.2%)
server989410361-194 (-4.6%)
vueClient1132312567-533 (-10.2%)
vueServer1084911312-191 (-4.1%)
Benchmarkv2 meanv3 meanDelta
@​unhead/vue0.106ms0.072ms32% faster
core0.088ms0.073ms17% faster

Key optimizations:

  • Client-only CAPO sorting (#​626)
  • Pure, tree-shakeable core with no side effects (#​632)
  • Minified internal DOM state properties (#​635)
  • Migrated unplugins from estree-walker/acorn-loose to oxc-walker (#​663)
  • Walker-based transformHtmlTemplate (#​581)
  • TemplateParamsPlugin and AliasSortingPlugin made opt-in for smaller bundles (#​493, #​494)

📊 Schema.org

  • 12 new nodes: Dataset, MusicAlbum, MusicGroup, MusicPlaylist, MusicRecording, PodcastEpisode, PodcastSeason, PodcastSeries, Service, TVEpisode, TVSeason, TVSeries (#​612)
  • Graph resolution rewrite for correctness and performance (#​616)
  • Removed ohash and defu dependencies (#​605)

🔄 Other Changes

  • renderDOMHead() / renderSSRHead() are now fully synchronous, single-pass via a composable resolveTags() pipeline; the head instance exposes a pluggable render() function for framework integrations (#​619, #​622, #​628, #​629, #​630)
  • @unhead/react/helmet drop-in compat export for users migrating from react-helmet (#​719)
  • useHeadSafe() now whitelists CSS styles (#​491)
  • Support for blocking attribute on scripts and stylesheets (#​489)
  • useScript() consolidated back into core, legacy support dropped (#​498)
  • fediverse:creator meta tag support (#​703)
  • Switched from hookable to lighter HookableCore with sync-only hooks (#​631)
  • Deprecation warnings added to aliased packages (@unhead/schema, @unhead/shared) (#​678)
  • templateParams extensible via module augmentation (#​679)
  • Respect user-provided twitter:card in InferSeoMetaPlugin (#​681)
  • Enforce as attribute for preload links (#​683)
  • onRendered callback option on useHead() for synchronizing with DOM head updates (#​712)
  • tagWeight option on createHead() to override default CAPO tag weight function (#​716)

🐛 Bug Fixes

  • Hydration race condition with deferred patches (#​634)
  • Process pending patches even when dirty is false (#​636)
  • Deduplicate matching tags inside same render cycle (#​668)
  • Dedupe <link rel="alternate"> correctly (#​655, #​656, #​658)
  • React: dispose head entries on unmount in StrictMode (#​664)
  • React: force invalidation on entry disposal (#​559)
  • Vue: support computed getter trigger (#​638)
  • Vue: expose @unhead/vue/stream/iife with correct types (#​707)
  • Scripts: prevent scope disposal from aborting unrelated trigger (#​660)
  • Schema.org: allow null to opt out of default values (#​680)
  • Schema.org: normalize target to array before merging potentialAction (#​709)
  • Avoid mutating cached titleTemplate tag in resolveTitleTemplate (#​715)

⚠️ Breaking Changes

Synchronous rendering

renderDOMHead() and renderSSRHead() no longer return promises. Remove await.

Build plugins: @unhead/addons@unhead/bundler (#​726, #​733)

The @unhead/addons package has been renamed to @unhead/bundler (the old name still works with a deprecation warning). Framework Vite plugins now use a namedUnhead export and ship from each framework's /vite subpath:

- import unhead from '@&#8203;unhead/addons/vite'+ import { Unhead } from '@&#8203;unhead/vue/vite'
// or @&#8203;unhead/react/vite, @&#8203;unhead/svelte/vite, @&#8203;unhead/solid-js/vite
export default defineConfig({
- plugins: [unhead()],+ plugins: [Unhead()],
})
Strict Link / Script / Meta types (#​729)

Link and Script unions no longer fall back to GenericLink / GenericScript, so the type system enforces per-tag constraints (e.g. preload + as: 'font' requires crossorigin). Meta content is now required; use content: null explicitly to remove a meta tag. Custom rel / type values need satisfies GenericLink / satisfies GenericScript.

Dropped deprecations (#​624)
OldNew
childreninnerHTML
hid / vmidkey
body: truetagPosition: 'bodyClose'
useServerHead / useServerSeoMetauseHead / useSeoMeta
createHeadCorecreateUnhead
@unhead/vue/legacy@unhead/vue/client or @unhead/vue/server (legacy path still works with deprecation warning)
mode option on entriesUse client/server createHead imports
CJS removed (#​482)

All packages are ESM-only.

Plugins now opt-in

TemplateParamsPlugin and AliasSortingPlugin are no longer included by default. Import and register them explicitly if needed.

Hooks removed
  • init hook removed
  • dom:renderTag, dom:rendered hooks deprecated (will be removed in v4)
  • dom:beforeRender is now synchronous (no async handlers)
Type changes
RemovedReplacement
HeadHeadTag
MetaFlatInputMetaFlat
RuntimeModeRemoved
@unhead/schemaunhead/types
@unhead/sharedunhead
Schema.org
  • PluginSchemaOrg / SchemaOrgUnheadPlugin replaced with UnheadSchemaOrg
  • canonicalHost replaced with host, canonicalUrl replaced with host + path

🔧 Migration Tooling

Add ValidatePlugin during your upgrade to automatically detect v2 patterns:

import{ValidatePlugin}from'unhead/plugins'createHead({plugins: [ValidatePlugin()]})

It will warn about missing plugins, deprecated properties, and other common migration issues. Remove it once migration is complete. If you use the unified Vite plugin, ValidatePlugin is auto-injected in dev so you don't have to wire it up manually. See PRs #​722, #​733.

📖 Migration Guide

See the full Migration Guide for detailed upgrade instructions.

Changelog

🚨 Breaking Changes
🚀 Features
🐞 Bug Fixes
🏎 Performance
View changes on GitHub

v2.1.15

Compare Source

No significant changes

View changes on GitHub

v2.1.13

Compare Source

🐞 Bug Fixes
  • schema-org: Normalize target to array before merging potentialAction - by @​harlan-zw and Claude Opus 4.6 (1M context) in #​709(22ac9)
View changes on GitHub

v2.1.12

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.11

Compare Source

⚠️ Security
  • Fixed XSS bypass in useHeadSafe via attribute name injection (GHSA-g5xx-pwrp-g3fv). Users handling untrusted input with useHeadSafe should upgrade immediately.
🐞 Bug Fixes
View changes on GitHub

v2.1.10

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.9

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.8

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.7

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.6

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.5

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.4

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.3

Compare Source

🐞 Bug Fixes
🏎 Performance
View changes on GitHub

v2.1.2

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.1.1

Compare Source

No significant changes

View changes on GitHub

v2.1.0

Compare Source

🚀 Features
🐞 Bug Fixes
🏎 Performance
View changes on GitHub

v2.0.19

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.0.18

Compare Source

🏎 Performance
View changes on GitHub

v2.0.17

Compare Source

No significant changes

View changes on GitHub

v2.0.14

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.0.13

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.0.12

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.0.11

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.0.10

Compare Source

🐞 Bug Fixes
View changes on GitHub

v2.0.9

Compare Source

🏎 Performance
View changes on GitHub

[v2.0.8](https://redirect.github.com/unjs/unhead/releases/ta

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • "on Monday"
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@vercel

vercelBot commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
scripts-playgroundErrorErrorMay 21, 2026 1:27am

@pkg-pr-new

pkg-pr-newBot commented Apr 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/scripts@703

commit: d236805

@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from cfd49b4 to 4530f70CompareApril 14, 2026 03:07
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 4530f70 to 437534aCompareApril 14, 2026 03:14
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 437534a to b1db17aCompareApril 14, 2026 09:44
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from b1db17a to 68cf660CompareApril 14, 2026 12:41
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 68cf660 to 916af97CompareApril 15, 2026 15:22
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 916af97 to 6236b11CompareApril 17, 2026 02:28
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 6236b11 to 3277c7aCompareApril 22, 2026 19:51
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 3277c7a to 39eaae6CompareApril 23, 2026 05:23
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 39eaae6 to 47586a9CompareApril 23, 2026 07:28
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 47586a9 to d04a0feCompareApril 27, 2026 03:05
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from d04a0fe to 7963b1bCompareApril 27, 2026 12:24
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 7963b1b to eef75faCompareApril 28, 2026 03:33
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from eef75fa to 00c4169CompareApril 29, 2026 17:16
@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from 00c4169 to 9762addCompareMay 1, 2026 01:13
@socket-security

socket-securityBot commented May 18, 2026

Copy link
Copy Markdown

@renovate
renovateBotforce-pushed the renovate/major-unhead-monorepo branch from ca351a1 to d236805CompareMay 21, 2026 01:27
@renovate
renovateBot deleted the renovate/major-unhead-monorepo branch May 27, 2026 04:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants