$npx -y skills add skilld-dev/vue-ecosystem-skills --skill unhead-vue-skilldFull-stack head manager built for Vue. ALWAYS use when writing code importing \"@unhead/vue\". Consult for debugging, best practices, or modifying @unhead/vue, unhead/vue, unhead vue, unhead.
| 1 | # unjs/unhead `@unhead/vue@3.1.0` |
| 2 | **Tags:** next: 3.0.0-beta.9, beta: 3.0.0-beta.12, rc: 3.0.0-rc.4 |
| 3 | |
| 4 | **References:** [Docs](./references/docs/_INDEX.md) |
| 5 | ## API Changes |
| 6 | |
| 7 | This section documents version-specific API changes — prioritize recent major/minor releases. |
| 8 | |
| 9 | - BREAKING: `createHead()` and `createServerHead()` removed from `@unhead/vue` root in v2 — use subpath imports: `createHead()` from `@unhead/vue/client` (SPA) or `@unhead/vue/server` (SSR); `createServerHead()` no longer exists [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#client--server-subpath-exports) |
| 10 | |
| 11 | - BREAKING: Implicit context removed in v2 — `setHeadInjectionHandler()` deleted; `useHead()` called after an `await` in lifecycle hooks (e.g. `onMounted`) throws because Vue context is lost; wrap async data fetching before calling `useHead()` [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#removed-implicit-context) |
| 12 | |
| 13 | - BREAKING: `vmid` and `hid` tag properties removed in v2 — use `key` for deduplication: `script: [{ key: 'my-key' }]` [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#removed-vmid-hid-children-body) |
| 14 | |
| 15 | - BREAKING: `children` tag property removed in v2 — use `innerHTML` instead [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#removed-vmid-hid-children-body) |
| 16 | |
| 17 | - BREAKING: `body: true` tag property removed in v2 — use `tagPosition: 'bodyClose'` instead [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#removed-vmid-hid-children-body) |
| 18 | |
| 19 | - BREAKING: `useScript()` no longer returns a Promise in v2 — `.then()` calls silently fail; use `.onLoaded(() => ...)` instead [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#updated-usescript) |
| 20 | |
| 21 | - BREAKING: `useScript()` API no longer accessible directly on the instance in v2 — must use `.proxy` explicitly: `script.proxy.myFn()` not `script.myFn()`; code compiles but calls are lost at runtime [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#updated-usescript) |
| 22 | |
| 23 | - BREAKING: `stub()` option and `script:instance-fn` hook removed from `useScript()` in v2 — replace with custom `use()` logic [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#updated-usescript) |
| 24 | |
| 25 | - BREAKING: Promise inputs in `useHead()` no longer auto-resolved in v2 — await the promise before passing, or opt in to `PromisePlugin` from `@unhead/vue/plugins` [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#promise-input-support) |
| 26 | |
| 27 | - BREAKING: `TemplateParamsPlugin` and `AliasSortingPlugin` no longer built-in in v2 — must opt in: `createHead({ plugins: [TemplateParamsPlugin, AliasSortingPlugin] })` imported from `@unhead/vue/plugins` [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#opt-in-template-params--tag-alias-sorting) |
| 28 | |
| 29 | - BREAKING: Capo.js tag sorting is now the default in v2 — breaks snapshot tests; opt out with `createHead({ disableCapoSorting: true })` [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#tag-sorting-updated) |
| 30 | |
| 31 | - DEPRECATED: `useServerHead()`, `useServerHeadSafe()`, `useServerSeoMeta()` — use `useHead()`, `useHeadSafe()`, `useSeoMeta()` with `import.meta.server` conditionals or `{ mode: 'server' }` option for tree-shaking |
| 32 | |
| 33 | - NEW: `<Head>`, `<Title>`, `<Meta>`, `<Link>`, `<Script>` template components — import from `@unhead/vue/components` [source](./references/docs/0.vue/head/guides/1.core-concepts/1.components.md:L8) |
| 34 | |
| 35 | - NEW: `DeprecationsPlugin` from `@unhead/vue/plugins` — re-enables removed `vmid`, `hid`, `children`, `body` properties for gradual migration to v2 [source](./references/docs/0.vue/head/guides/0.get-started/1.migration.md#removed-vmid-hid-children-body) |
| 36 | |
| 37 | **Also changed:** `@unhead/schema` deprecated — use `@unhead/vue/types` instead · `createHeadCore` deprecated — use `createUnhead` · Default SSR tags auto-inserted in v2 (`charset`, `viewport`, `html lang="en"`); disable with `createHead({ disableDefaults: true })` · CJS exports removed, ESM only · Vue 2 support removed · `useHead()` context lost after `async` in Vue lifecycle hooks — fetch data first, then call `useHead()` |
| 38 | |
| 39 | ## Best Practices |
| 40 | |
| 41 | - Always use `injectHead()` from `@unhead/vue` instead of `getActiveHead()` from `unhead` in Vue components — `injectHead()` binds to the Vue component context (visible in `onServerPrefetch`), while `getActiveHead()` returns a shared cross-request instance that breaks in SSR. The maintainer confirmed this is the correct approach for Vue. [source](./references/discussions/discussion-362.md) |
| 42 | |
| 43 | - Avoid calling `useHead()` inside watchers — |