@unhead/vue 3.0.4 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ import * as _unhead_bundler_framework from '@unhead/bundler/framework';
2
+ import { UnheadFrameworkOptions } from '@unhead/bundler/framework';
3
+ import { U as UnheadVueStreamingOptions } from './shared/vue.B_EhRTsW.mjs';
4
+ import 'unplugin';
5
+ import 'unhead/stream/unplugin';
6
+
7
+ type UnheadVueOptions = UnheadFrameworkOptions<UnheadVueStreamingOptions>;
8
+ /**
9
+ * Unified bundler plugin factory for `@unhead/vue`. Returns an object with
10
+ * per-bundler dispatch methods (`vite`, `webpack`, `rspack`, `rollup`) so a
11
+ * single call site covers every supported builder.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * // vite:
16
+ * import { Unhead } from '@unhead/vue/bundler'
17
+ * export default defineConfig({ plugins: [...Unhead({ streaming: true }).vite()] })
18
+ *
19
+ * // nuxt kit:
20
+ * addBuildPlugin(Unhead({ streaming: true }))
21
+ * ```
22
+ */
23
+ declare const Unhead: (options?: UnheadFrameworkOptions<UnheadVueStreamingOptions>) => _unhead_bundler_framework.UnheadBundlerFactory;
24
+
25
+ export { Unhead };
26
+ export type { UnheadVueOptions };
@@ -0,0 +1,26 @@
1
+ import * as _unhead_bundler_framework from '@unhead/bundler/framework';
2
+ import { UnheadFrameworkOptions } from '@unhead/bundler/framework';
3
+ import { U as UnheadVueStreamingOptions } from './shared/vue.B_EhRTsW.js';
4
+ import 'unplugin';
5
+ import 'unhead/stream/unplugin';
6
+
7
+ type UnheadVueOptions = UnheadFrameworkOptions<UnheadVueStreamingOptions>;
8
+ /**
9
+ * Unified bundler plugin factory for `@unhead/vue`. Returns an object with
10
+ * per-bundler dispatch methods (`vite`, `webpack`, `rspack`, `rollup`) so a
11
+ * single call site covers every supported builder.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * // vite:
16
+ * import { Unhead } from '@unhead/vue/bundler'
17
+ * export default defineConfig({ plugins: [...Unhead({ streaming: true }).vite()] })
18
+ *
19
+ * // nuxt kit:
20
+ * addBuildPlugin(Unhead({ streaming: true }))
21
+ * ```
22
+ */
23
+ declare const Unhead: (options?: UnheadFrameworkOptions<UnheadVueStreamingOptions>) => _unhead_bundler_framework.UnheadBundlerFactory;
24
+
25
+ export { Unhead };
26
+ export type { UnheadVueOptions };
@@ -0,0 +1,11 @@
1
+ import { createFrameworkPlugin } from '@unhead/bundler/framework';
2
+ import { u as unheadVueStreamingPlugin } from './shared/vue.D3FlIlye.mjs';
3
+ import 'unhead/stream/unplugin';
4
+ import 'unplugin';
5
+
6
+ const Unhead = createFrameworkPlugin({
7
+ framework: "@unhead/vue",
8
+ streamingPlugin: unheadVueStreamingPlugin
9
+ });
10
+
11
+ export { Unhead };
package/dist/client.mjs CHANGED
@@ -1,10 +1,11 @@
1
1
  import { createDomRenderer, createDebouncedFn, createHead as createHead$1 } from 'unhead/client';
2
2
  export { renderDOMHead } from 'unhead/client';
3
- import { v as vueInstall } from './shared/vue.D51lypTh.mjs';
4
- export { V as VueHeadMixin } from './shared/vue.C54fV9ES.mjs';
3
+ import { v as vueInstall } from './shared/vue.Kp0sxz0n.mjs';
4
+ export { V as VueHeadMixin } from './shared/vue.BIIm5xba.mjs';
5
+ import 'vue';
6
+ import './shared/vue.Cn5tnr29.mjs';
5
7
  import 'unhead/plugins';
6
8
  import 'unhead/utils';
7
- import 'vue';
8
9
  import './shared/vue.CkLIG7eN.mjs';
9
10
 
10
11
  // @__NO_SIDE_EFFECTS__
@@ -1,7 +1,8 @@
1
1
  import { defineComponent, ref, onBeforeUnmount, watchEffect } from 'vue';
2
- import { u as useHead } from './shared/vue.D51lypTh.mjs';
2
+ import { u as useHead } from './shared/vue.Cn5tnr29.mjs';
3
3
  import 'unhead/plugins';
4
4
  import 'unhead/utils';
5
+ import './shared/vue.Kp0sxz0n.mjs';
5
6
  import './shared/vue.CkLIG7eN.mjs';
6
7
 
7
8
  function extractTextContent(children) {
package/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
- export { h as headSymbol, i as injectHead, u as useHead, a as useHeadSafe, b as useSeoMeta, c as useServerHead, d as useServerHeadSafe, e as useServerSeoMeta } from './shared/vue.D51lypTh.mjs';
1
+ export { i as injectHead, u as useHead, a as useHeadSafe, b as useSeoMeta, c as useServerHead, d as useServerHeadSafe, e as useServerSeoMeta } from './shared/vue.Cn5tnr29.mjs';
2
+ export { h as headSymbol } from './shared/vue.Kp0sxz0n.mjs';
2
3
  export { resolveUnrefHeadInput } from './utils.mjs';
3
- export { V as VueHeadMixin } from './shared/vue.C54fV9ES.mjs';
4
+ export { V as VueHeadMixin } from './shared/vue.BIIm5xba.mjs';
4
5
  export { createUnhead, defineLink, defineScript } from 'unhead';
5
- export { u as useScript } from './shared/vue.CC8Cvdls.mjs';
6
+ export { u as useScript } from './shared/vue.D__tEKct.mjs';
6
7
  import 'unhead/plugins';
7
8
  import 'unhead/utils';
8
9
  import 'vue';
package/dist/legacy.mjs CHANGED
@@ -2,13 +2,14 @@ import { DeprecationsPlugin } from 'unhead/legacy';
2
2
  import { PromisesPlugin, TemplateParamsPlugin, AliasSortingPlugin } from 'unhead/plugins';
3
3
  import { createHead as createHead$1 } from './client.mjs';
4
4
  import { createHead as createHead$2 } from './server.mjs';
5
- export { V as VueHeadMixin } from './shared/vue.C54fV9ES.mjs';
5
+ export { V as VueHeadMixin } from './shared/vue.BIIm5xba.mjs';
6
6
  export { renderDOMHead } from 'unhead/client';
7
- import './shared/vue.D51lypTh.mjs';
8
- import 'unhead/utils';
9
- import 'vue';
10
- import './shared/vue.CkLIG7eN.mjs';
7
+ import './shared/vue.Kp0sxz0n.mjs';
11
8
  import 'unhead/server';
9
+ import './shared/vue.CkLIG7eN.mjs';
10
+ import 'vue';
11
+ import './shared/vue.Cn5tnr29.mjs';
12
+ import 'unhead/utils';
12
13
 
13
14
  const legacyPlugins = [DeprecationsPlugin, PromisesPlugin, TemplateParamsPlugin, AliasSortingPlugin];
14
15
  // @__NO_SIDE_EFFECTS__
package/dist/scripts.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  export { createSpyProxy } from 'unhead/scripts';
2
- export { u as useScript } from './shared/vue.CC8Cvdls.mjs';
2
+ export { u as useScript } from './shared/vue.D__tEKct.mjs';
3
3
  import 'vue';
4
- import './shared/vue.D51lypTh.mjs';
4
+ import './shared/vue.Cn5tnr29.mjs';
5
5
  import 'unhead/plugins';
6
6
  import 'unhead/utils';
7
+ import './shared/vue.Kp0sxz0n.mjs';
7
8
  import './shared/vue.CkLIG7eN.mjs';
package/dist/server.mjs CHANGED
@@ -1,11 +1,12 @@
1
1
  import { createHead as createHead$1 } from 'unhead/server';
2
2
  export { propsToString, renderSSRHead, transformHtmlTemplate } from 'unhead/server';
3
- import { v as vueInstall } from './shared/vue.D51lypTh.mjs';
3
+ import { v as vueInstall } from './shared/vue.Kp0sxz0n.mjs';
4
4
  import { V as VueResolver } from './shared/vue.CkLIG7eN.mjs';
5
- export { V as VueHeadMixin } from './shared/vue.C54fV9ES.mjs';
5
+ export { V as VueHeadMixin } from './shared/vue.BIIm5xba.mjs';
6
+ import 'vue';
7
+ import './shared/vue.Cn5tnr29.mjs';
6
8
  import 'unhead/plugins';
7
9
  import 'unhead/utils';
8
- import 'vue';
9
10
 
10
11
  // @__NO_SIDE_EFFECTS__
11
12
  function createHead(options = {}) {
@@ -1,5 +1,5 @@
1
1
  import { getCurrentInstance } from 'vue';
2
- import { u as useHead } from './vue.D51lypTh.mjs';
2
+ import { u as useHead } from './vue.Cn5tnr29.mjs';
3
3
 
4
4
  const VueHeadMixin = {
5
5
  created() {
@@ -0,0 +1,16 @@
1
+ import * as unplugin from 'unplugin';
2
+ import { StreamingPluginOptions } from 'unhead/stream/unplugin';
3
+
4
+ type UnheadVueStreamingOptions = Pick<StreamingPluginOptions, 'mode'>;
5
+ /**
6
+ * Bundler-agnostic streaming SSR plugin for `@unhead/vue`.
7
+ *
8
+ * Vue does not need a source-level transform: per-chunk head patches are
9
+ * emitted by `wrapStream` on the server as self-deleting inline scripts.
10
+ * This plugin exists to wire the client streaming bootstrap (virtual iife
11
+ * module + `transformIndexHtml` head-prepend on vite).
12
+ */
13
+ declare const unheadVueStreamingPlugin: unplugin.UnpluginInstance<UnheadVueStreamingOptions | undefined, boolean>;
14
+
15
+ export { unheadVueStreamingPlugin as u };
16
+ export type { UnheadVueStreamingOptions as U };
@@ -0,0 +1,16 @@
1
+ import * as unplugin from 'unplugin';
2
+ import { StreamingPluginOptions } from 'unhead/stream/unplugin';
3
+
4
+ type UnheadVueStreamingOptions = Pick<StreamingPluginOptions, 'mode'>;
5
+ /**
6
+ * Bundler-agnostic streaming SSR plugin for `@unhead/vue`.
7
+ *
8
+ * Vue does not need a source-level transform: per-chunk head patches are
9
+ * emitted by `wrapStream` on the server as self-deleting inline scripts.
10
+ * This plugin exists to wire the client streaming bootstrap (virtual iife
11
+ * module + `transformIndexHtml` head-prepend on vite).
12
+ */
13
+ declare const unheadVueStreamingPlugin: unplugin.UnpluginInstance<UnheadVueStreamingOptions | undefined, boolean>;
14
+
15
+ export { unheadVueStreamingPlugin as u };
16
+ export type { UnheadVueStreamingOptions as U };
@@ -1,21 +1,9 @@
1
1
  import { SafeInputPlugin, FlatMetaPlugin } from 'unhead/plugins';
2
2
  import { walkResolver } from 'unhead/utils';
3
3
  import { hasInjectionContext, inject, ref, getCurrentScope, watchEffect, getCurrentInstance, onBeforeUnmount, onDeactivated, onActivated } from 'vue';
4
+ import { h as headSymbol } from './vue.Kp0sxz0n.mjs';
4
5
  import { V as VueResolver } from './vue.CkLIG7eN.mjs';
5
6
 
6
- const headSymbol = "usehead";
7
- // @__NO_SIDE_EFFECTS__
8
- function vueInstall(head) {
9
- const plugin = {
10
- install(app) {
11
- app.config.globalProperties.$unhead = head;
12
- app.config.globalProperties.$head = head;
13
- app.provide(headSymbol, head);
14
- }
15
- };
16
- return plugin.install;
17
- }
18
-
19
7
  // @__NO_SIDE_EFFECTS__
20
8
  function injectHead() {
21
9
  if (hasInjectionContext()) {
@@ -82,4 +70,4 @@ const useServerHead = useHead;
82
70
  const useServerHeadSafe = useHeadSafe;
83
71
  const useServerSeoMeta = useSeoMeta;
84
72
 
85
- export { useHeadSafe as a, useSeoMeta as b, useServerHead as c, useServerHeadSafe as d, useServerSeoMeta as e, headSymbol as h, injectHead as i, useHead as u, vueInstall as v };
73
+ export { useHeadSafe as a, useSeoMeta as b, useServerHead as c, useServerHeadSafe as d, useServerSeoMeta as e, injectHead as i, useHead as u };
@@ -0,0 +1,11 @@
1
+ import { buildStreamingPluginOptions } from 'unhead/stream/unplugin';
2
+ import { createUnplugin } from 'unplugin';
3
+
4
+ const unheadVueStreamingPlugin = createUnplugin(
5
+ (options = {}) => buildStreamingPluginOptions({
6
+ framework: "@unhead/vue",
7
+ mode: options.mode
8
+ })
9
+ );
10
+
11
+ export { unheadVueStreamingPlugin as u };
@@ -1,6 +1,6 @@
1
1
  import { useScript as useScript$1 } from 'unhead/scripts';
2
2
  import { getCurrentInstance, onMounted, isRef, watch, onScopeDispose, ref } from 'vue';
3
- import { i as injectHead } from './vue.D51lypTh.mjs';
3
+ import { i as injectHead } from './vue.Cn5tnr29.mjs';
4
4
 
5
5
  function registerVueScopeHandlers(script, scope) {
6
6
  if (!scope) {
@@ -0,0 +1,14 @@
1
+ const headSymbol = "usehead";
2
+ // @__NO_SIDE_EFFECTS__
3
+ function vueInstall(head) {
4
+ const plugin = {
5
+ install(app) {
6
+ app.config.globalProperties.$unhead = head;
7
+ app.config.globalProperties.$head = head;
8
+ app.provide(headSymbol, head);
9
+ }
10
+ };
11
+ return plugin.install;
12
+ }
13
+
14
+ export { headSymbol as h, vueInstall as v };
@@ -1,17 +1,13 @@
1
- import * as vue from 'vue';
2
1
  import { CreateStreamableClientHeadOptions } from 'unhead/stream/client';
3
2
  export { CreateStreamableClientHeadOptions, UnheadStreamQueue } from 'unhead/stream/client';
4
3
  export { V as VueHeadMixin } from '../shared/vue.DnywREVF.mjs';
5
4
  import { V as VueHeadClient, U as UseHeadInput } from '../shared/vue.CajUUuy2.mjs';
6
5
  import 'unhead/types';
6
+ import 'vue';
7
7
 
8
- /**
9
- * Client-side HeadStream - renders nothing (script already executed during SSR streaming)
10
- */
11
- declare const HeadStream: vue.DefineComponent<{}, () => null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
12
8
  /**
13
9
  * Creates a client head by wrapping the core instance from the iife script.
14
10
  */
15
11
  declare function createStreamableHead(options?: CreateStreamableClientHeadOptions): VueHeadClient<UseHeadInput, boolean> | undefined;
16
12
 
17
- export { HeadStream, VueHeadClient, createStreamableHead };
13
+ export { VueHeadClient, createStreamableHead };
@@ -1,17 +1,13 @@
1
- import * as vue from 'vue';
2
1
  import { CreateStreamableClientHeadOptions } from 'unhead/stream/client';
3
2
  export { CreateStreamableClientHeadOptions, UnheadStreamQueue } from 'unhead/stream/client';
4
3
  export { V as VueHeadMixin } from '../shared/vue.DnywREVF.js';
5
4
  import { V as VueHeadClient, U as UseHeadInput } from '../shared/vue.CajUUuy2.js';
6
5
  import 'unhead/types';
6
+ import 'vue';
7
7
 
8
- /**
9
- * Client-side HeadStream - renders nothing (script already executed during SSR streaming)
10
- */
11
- declare const HeadStream: vue.DefineComponent<{}, () => null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
12
8
  /**
13
9
  * Creates a client head by wrapping the core instance from the iife script.
14
10
  */
15
11
  declare function createStreamableHead(options?: CreateStreamableClientHeadOptions): VueHeadClient<UseHeadInput, boolean> | undefined;
16
12
 
17
- export { HeadStream, VueHeadClient, createStreamableHead };
13
+ export { VueHeadClient, createStreamableHead };
@@ -1,17 +1,12 @@
1
1
  import { createStreamableHead as createStreamableHead$1 } from 'unhead/stream/client';
2
- import { defineComponent } from 'vue';
3
- import { v as vueInstall } from '../shared/vue.D51lypTh.mjs';
2
+ import { v as vueInstall } from '../shared/vue.Kp0sxz0n.mjs';
4
3
  import { V as VueResolver } from '../shared/vue.CkLIG7eN.mjs';
5
- export { V as VueHeadMixin } from '../shared/vue.C54fV9ES.mjs';
4
+ export { V as VueHeadMixin } from '../shared/vue.BIIm5xba.mjs';
5
+ import 'vue';
6
+ import '../shared/vue.Cn5tnr29.mjs';
6
7
  import 'unhead/plugins';
7
8
  import 'unhead/utils';
8
9
 
9
- const HeadStream = defineComponent({
10
- name: "HeadStream",
11
- setup() {
12
- return () => null;
13
- }
14
- });
15
10
  // @__NO_SIDE_EFFECTS__
16
11
  function createStreamableHead(options = {}) {
17
12
  const head = createStreamableHead$1({
@@ -24,4 +19,4 @@ function createStreamableHead(options = {}) {
24
19
  return head;
25
20
  }
26
21
 
27
- export { HeadStream, createStreamableHead };
22
+ export { createStreamableHead };
@@ -1,16 +1,9 @@
1
- import * as vue from 'vue';
2
1
  import { WebStreamableHeadContext } from 'unhead/stream/server';
3
2
  export { CreateStreamableServerHeadOptions, StreamingTemplateParts, createBootstrapScript, prepareStreamingTemplate, renderSSRHeadShell, renderSSRHeadSuspenseChunk, renderShell, wrapStream } from 'unhead/stream/server';
4
3
  import { ResolvableHead, SSRHeadPayload, CreateStreamableServerHeadOptions } from 'unhead/types';
5
4
  import { V as VueHeadClient } from '../shared/vue.CajUUuy2.mjs';
5
+ import 'vue';
6
6
 
7
- /**
8
- * Streaming script component - outputs inline script with current head state.
9
- * The Vite plugin with streaming: true auto-injects this.
10
- */
11
- declare const HeadStream: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
12
- [key: string]: any;
13
- }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
14
7
  /**
15
8
  * Vue-specific context returned by createStreamableHead.
16
9
  * Extends WebStreamableHeadContext with Vue-specific head type.
@@ -24,6 +17,17 @@ interface VueStreamableHeadContext extends Omit<WebStreamableHeadContext<Resolva
24
17
  /**
25
18
  * Creates a head instance configured for Vue streaming SSR.
26
19
  *
20
+ * `wrapStream` is Vue-specific: Vue's `renderToWebStream` flushes chunks in
21
+ * document order per resolved Suspense boundary, so any head entries added
22
+ * during a chunk's render can be emitted as a self-deleting inline
23
+ * `<script>` right after the chunk. The script executes at HTML parse
24
+ * (updating the client head state progressively) and calls
25
+ * `document.currentScript.remove()` so the DOM is clean before Vue
26
+ * hydrates. This pattern is not safe for frameworks with out-of-order
27
+ * Suspense reveals (React, Solid) or framework-specific chunk formats
28
+ * (Svelte) — those continue to use an in-tree `<HeadStream />` component
29
+ * whose output is serialized inside the framework's own stream.
30
+ *
27
31
  * @example
28
32
  * ```ts
29
33
  * export async function render(url: string, template: string) {
@@ -34,10 +38,7 @@ interface VueStreamableHeadContext extends Omit<WebStreamableHeadContext<Resolva
34
38
  * app.mixin(VueHeadMixin)
35
39
  * router.push(url)
36
40
  *
37
- * // Create stream first - Vue starts rendering synchronously
38
41
  * const vueStream = renderToWebStream(app)
39
- *
40
- * // Wait for router - by now Vue's sync render has pushed head entries
41
42
  * await router.isReady()
42
43
  *
43
44
  * return wrapStream(vueStream, template)
@@ -46,5 +47,5 @@ interface VueStreamableHeadContext extends Omit<WebStreamableHeadContext<Resolva
46
47
  */
47
48
  declare function createStreamableHead(options?: Omit<CreateStreamableServerHeadOptions, 'propsResolver'>): VueStreamableHeadContext;
48
49
 
49
- export { HeadStream, VueHeadClient, createStreamableHead };
50
+ export { VueHeadClient, createStreamableHead };
50
51
  export type { VueStreamableHeadContext };
@@ -1,16 +1,9 @@
1
- import * as vue from 'vue';
2
1
  import { WebStreamableHeadContext } from 'unhead/stream/server';
3
2
  export { CreateStreamableServerHeadOptions, StreamingTemplateParts, createBootstrapScript, prepareStreamingTemplate, renderSSRHeadShell, renderSSRHeadSuspenseChunk, renderShell, wrapStream } from 'unhead/stream/server';
4
3
  import { ResolvableHead, SSRHeadPayload, CreateStreamableServerHeadOptions } from 'unhead/types';
5
4
  import { V as VueHeadClient } from '../shared/vue.CajUUuy2.js';
5
+ import 'vue';
6
6
 
7
- /**
8
- * Streaming script component - outputs inline script with current head state.
9
- * The Vite plugin with streaming: true auto-injects this.
10
- */
11
- declare const HeadStream: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
12
- [key: string]: any;
13
- }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
14
7
  /**
15
8
  * Vue-specific context returned by createStreamableHead.
16
9
  * Extends WebStreamableHeadContext with Vue-specific head type.
@@ -24,6 +17,17 @@ interface VueStreamableHeadContext extends Omit<WebStreamableHeadContext<Resolva
24
17
  /**
25
18
  * Creates a head instance configured for Vue streaming SSR.
26
19
  *
20
+ * `wrapStream` is Vue-specific: Vue's `renderToWebStream` flushes chunks in
21
+ * document order per resolved Suspense boundary, so any head entries added
22
+ * during a chunk's render can be emitted as a self-deleting inline
23
+ * `<script>` right after the chunk. The script executes at HTML parse
24
+ * (updating the client head state progressively) and calls
25
+ * `document.currentScript.remove()` so the DOM is clean before Vue
26
+ * hydrates. This pattern is not safe for frameworks with out-of-order
27
+ * Suspense reveals (React, Solid) or framework-specific chunk formats
28
+ * (Svelte) — those continue to use an in-tree `<HeadStream />` component
29
+ * whose output is serialized inside the framework's own stream.
30
+ *
27
31
  * @example
28
32
  * ```ts
29
33
  * export async function render(url: string, template: string) {
@@ -34,10 +38,7 @@ interface VueStreamableHeadContext extends Omit<WebStreamableHeadContext<Resolva
34
38
  * app.mixin(VueHeadMixin)
35
39
  * router.push(url)
36
40
  *
37
- * // Create stream first - Vue starts rendering synchronously
38
41
  * const vueStream = renderToWebStream(app)
39
- *
40
- * // Wait for router - by now Vue's sync render has pushed head entries
41
42
  * await router.isReady()
42
43
  *
43
44
  * return wrapStream(vueStream, template)
@@ -46,5 +47,5 @@ interface VueStreamableHeadContext extends Omit<WebStreamableHeadContext<Resolva
46
47
  */
47
48
  declare function createStreamableHead(options?: Omit<CreateStreamableServerHeadOptions, 'propsResolver'>): VueStreamableHeadContext;
48
49
 
49
- export { HeadStream, VueHeadClient, createStreamableHead };
50
+ export { VueHeadClient, createStreamableHead };
50
51
  export type { VueStreamableHeadContext };
@@ -1,25 +1,9 @@
1
- import { renderSSRHeadSuspenseChunk, createStreamableHead as createStreamableHead$1, wrapStream } from 'unhead/stream/server';
1
+ import { createStreamableHead as createStreamableHead$1, prepareStreamingTemplate, renderSSRHeadSuspenseChunk } from 'unhead/stream/server';
2
2
  export { createBootstrapScript, prepareStreamingTemplate, renderSSRHeadShell, renderSSRHeadSuspenseChunk, renderShell, wrapStream } from 'unhead/stream/server';
3
- import { defineComponent, h } from 'vue';
4
- import { i as injectHead, v as vueInstall } from '../shared/vue.D51lypTh.mjs';
3
+ import { v as vueInstall } from '../shared/vue.Kp0sxz0n.mjs';
5
4
  import { V as VueResolver } from '../shared/vue.CkLIG7eN.mjs';
6
- import 'unhead/plugins';
7
- import 'unhead/utils';
5
+ import 'vue';
8
6
 
9
- const HeadStream = defineComponent({
10
- name: "HeadStream",
11
- setup() {
12
- const head = injectHead();
13
- return () => {
14
- if (!head._shellRendered?.())
15
- return null;
16
- const update = renderSSRHeadSuspenseChunk(head);
17
- if (!update)
18
- return null;
19
- return h("script", { innerHTML: update });
20
- };
21
- }
22
- });
23
7
  function createStreamableHead(options = {}) {
24
8
  const { head } = createStreamableHead$1({
25
9
  ...options,
@@ -27,17 +11,40 @@ function createStreamableHead(options = {}) {
27
11
  });
28
12
  const vueHead = head;
29
13
  vueHead.install = vueInstall(vueHead);
30
- let shellRendered = false;
31
- vueHead._shellRendered = () => shellRendered;
14
+ const encoder = new TextEncoder();
15
+ const flushPatch = (controller) => {
16
+ const patch = renderSSRHeadSuspenseChunk(vueHead);
17
+ if (patch)
18
+ controller.enqueue(encoder.encode(`<script>${patch};document.currentScript.remove()<\/script>`));
19
+ };
32
20
  return {
33
21
  head: vueHead,
34
- wrapStream: (stream, template) => {
35
- const preRenderedState = vueHead.render();
36
- vueHead.entries.clear();
37
- shellRendered = true;
38
- return wrapStream(vueHead, stream, template, preRenderedState);
39
- }
22
+ wrapStream: (stream, template) => new ReadableStream({
23
+ async start(controller) {
24
+ try {
25
+ const { shell, end } = prepareStreamingTemplate(vueHead, template);
26
+ controller.enqueue(encoder.encode(shell));
27
+ const reader = stream.getReader();
28
+ try {
29
+ while (true) {
30
+ const { done, value } = await reader.read();
31
+ if (done)
32
+ break;
33
+ controller.enqueue(value);
34
+ flushPatch(controller);
35
+ }
36
+ } finally {
37
+ reader.releaseLock();
38
+ }
39
+ flushPatch(controller);
40
+ controller.enqueue(encoder.encode(end));
41
+ controller.close();
42
+ } catch (error) {
43
+ controller.error(error);
44
+ }
45
+ }
46
+ })
40
47
  };
41
48
  }
42
49
 
43
- export { HeadStream, createStreamableHead };
50
+ export { createStreamableHead };
@@ -1,27 +1,14 @@
1
- import * as vite from 'vite';
2
- import { StreamingPluginOptions } from 'unhead/stream/vite';
1
+ import { Plugin } from 'vite';
2
+ import { U as UnheadVueStreamingOptions } from '../shared/vue.B_EhRTsW.mjs';
3
+ export { u as unheadVueStreamingPlugin } from '../shared/vue.B_EhRTsW.mjs';
4
+ import 'unplugin';
5
+ import 'unhead/stream/unplugin';
3
6
 
4
7
  /**
5
- * Vite plugin for Vue streaming SSR support.
6
- * Automatically injects HeadStream components into Vue SFC templates.
7
- *
8
- * @returns Vite plugin configuration object with:
9
- * - `name`: Plugin identifier
10
- * - `enforce`: Plugin execution order ('pre')
11
- * - `transform`: Transform hook for processing .vue files
12
- *
13
- * @example
14
- * ```ts
15
- * // vite.config.ts
16
- * import { unheadVuePlugin } from '@unhead/vue/stream/vite'
17
- *
18
- * export default {
19
- * plugins: [
20
- * unheadVuePlugin()
21
- * ]
22
- * }
23
- * ```
8
+ * @deprecated Use `Unhead({ streaming: true }).vite()` from `@unhead/vue/bundler` instead.
9
+ * The `@unhead/vue/stream/vite` subpath and `unheadVuePlugin` export will be
10
+ * removed in a future major release.
24
11
  */
25
- declare function unheadVuePlugin(options?: Pick<StreamingPluginOptions, 'mode'>): vite.Plugin<any>;
12
+ declare function unheadVuePlugin(options?: UnheadVueStreamingOptions): Plugin;
26
13
 
27
- export { unheadVuePlugin as default, unheadVuePlugin };
14
+ export { UnheadVueStreamingOptions, unheadVuePlugin as default, unheadVuePlugin };
@@ -1,27 +1,14 @@
1
- import * as vite from 'vite';
2
- import { StreamingPluginOptions } from 'unhead/stream/vite';
1
+ import { Plugin } from 'vite';
2
+ import { U as UnheadVueStreamingOptions } from '../shared/vue.B_EhRTsW.js';
3
+ export { u as unheadVueStreamingPlugin } from '../shared/vue.B_EhRTsW.js';
4
+ import 'unplugin';
5
+ import 'unhead/stream/unplugin';
3
6
 
4
7
  /**
5
- * Vite plugin for Vue streaming SSR support.
6
- * Automatically injects HeadStream components into Vue SFC templates.
7
- *
8
- * @returns Vite plugin configuration object with:
9
- * - `name`: Plugin identifier
10
- * - `enforce`: Plugin execution order ('pre')
11
- * - `transform`: Transform hook for processing .vue files
12
- *
13
- * @example
14
- * ```ts
15
- * // vite.config.ts
16
- * import { unheadVuePlugin } from '@unhead/vue/stream/vite'
17
- *
18
- * export default {
19
- * plugins: [
20
- * unheadVuePlugin()
21
- * ]
22
- * }
23
- * ```
8
+ * @deprecated Use `Unhead({ streaming: true }).vite()` from `@unhead/vue/bundler` instead.
9
+ * The `@unhead/vue/stream/vite` subpath and `unheadVuePlugin` export will be
10
+ * removed in a future major release.
24
11
  */
25
- declare function unheadVuePlugin(options?: Pick<StreamingPluginOptions, 'mode'>): vite.Plugin<any>;
12
+ declare function unheadVuePlugin(options?: UnheadVueStreamingOptions): Plugin;
26
13
 
27
- export { unheadVuePlugin as default, unheadVuePlugin };
14
+ export { UnheadVueStreamingOptions, unheadVuePlugin as default, unheadVuePlugin };
@@ -1,70 +1,9 @@
1
- import MagicString from 'magic-string';
2
- import { parseAndWalk } from 'oxc-walker';
3
- import { createStreamingPlugin } from 'unhead/stream/vite';
1
+ import { u as unheadVueStreamingPlugin } from '../shared/vue.D3FlIlye.mjs';
2
+ import 'unhead/stream/unplugin';
3
+ import 'unplugin';
4
4
 
5
- const TEMPLATE_RE = /<template[^>]*>/;
6
- const SCRIPT_RE = /<script[^>]*>/i;
7
- const FILTER_RE = /\.vue$/;
8
- function transform(code, id, isSSR, s) {
9
- if (!code.includes("useHead") && !code.includes("useSeoMeta") && !code.includes("useHeadSafe"))
10
- return false;
11
- const templateMatch = code.match(TEMPLATE_RE);
12
- if (!templateMatch)
13
- return false;
14
- const templateStart = templateMatch.index + templateMatch[0].length;
15
- s.appendRight(templateStart, "<HeadStream />");
16
- const importPath = `@unhead/vue/stream/${isSSR ? "server" : "client"}`;
17
- const scriptMatch = code.match(SCRIPT_RE);
18
- if (!scriptMatch)
19
- return true;
20
- const scriptEnd = scriptMatch.index + scriptMatch[0].length;
21
- const scriptCloseIndex = code.indexOf("<\/script>", scriptEnd);
22
- if (scriptCloseIndex === -1)
23
- return true;
24
- const scriptContent = code.slice(scriptEnd, scriptCloseIndex);
25
- let existingImport = null;
26
- parseAndWalk(scriptContent, id, {
27
- parseOptions: { lang: "ts" },
28
- enter(node) {
29
- if (node.type === "ImportDeclaration" && node.source.value === importPath) {
30
- existingImport = {
31
- start: scriptEnd + node.start,
32
- end: scriptEnd + node.end,
33
- specifiers: node.specifiers?.map((spec) => spec.local?.name).filter(Boolean) || []
34
- };
35
- this.skip();
36
- }
37
- }
38
- });
39
- const foundImport = existingImport;
40
- if (foundImport) {
41
- if (!foundImport.specifiers.includes("HeadStream")) {
42
- const inner = foundImport.specifiers.join(", ");
43
- const newImports = inner ? `${inner}, HeadStream` : "HeadStream";
44
- s.overwrite(foundImport.start, foundImport.end, `import { ${newImports} } from '${importPath}'
45
- `);
46
- }
47
- } else {
48
- s.appendRight(scriptEnd, `
49
- import { HeadStream } from '${importPath}'`);
50
- }
51
- return true;
52
- }
53
5
  function unheadVuePlugin(options) {
54
- return createStreamingPlugin({
55
- framework: "@unhead/vue",
56
- filter: FILTER_RE,
57
- mode: options?.mode,
58
- transform(code, id, opts) {
59
- const s = new MagicString(code);
60
- if (!transform(code, id, opts?.ssr ?? false, s))
61
- return null;
62
- return {
63
- code: s.toString(),
64
- map: s.generateMap({ includeContent: true, source: id })
65
- };
66
- }
67
- });
6
+ return unheadVueStreamingPlugin.vite(options);
68
7
  }
69
8
 
70
- export { unheadVuePlugin as default, unheadVuePlugin };
9
+ export { unheadVuePlugin as default, unheadVuePlugin, unheadVueStreamingPlugin };
package/dist/vite.d.mts CHANGED
@@ -1,33 +1,22 @@
1
- import { VitePluginOptions } from '@unhead/bundler/vite';
2
- import { StreamingPluginOptions } from 'unhead/stream/vite';
3
1
  import { Plugin } from 'vite';
2
+ import { UnheadVueOptions } from './bundler.mjs';
3
+ import '@unhead/bundler/framework';
4
+ import './shared/vue.B_EhRTsW.mjs';
5
+ import 'unplugin';
6
+ import 'unhead/stream/unplugin';
4
7
 
5
- interface UnheadVueViteOptions extends VitePluginOptions {
6
- /**
7
- * Enable streaming SSR support.
8
- * Set to `true` or a config object to enable.
9
- * @default false
10
- */
11
- streaming?: true | Pick<StreamingPluginOptions, 'mode'> | false;
12
- }
8
+ type UnheadVueViteOptions = UnheadVueOptions;
13
9
  /**
14
- * Unified Vite plugin for `@unhead/vue`.
15
- *
16
- * Combines build optimizations (tree-shaking, useSeoMeta transform, minification)
17
- * with streaming SSR support into a single plugin.
10
+ * Vite plugin for `@unhead/vue`. Kept for backwards compatibility; prefer
11
+ * the unified `@unhead/vue/bundler` entry which dispatches to all bundlers.
18
12
  *
19
13
  * @example
20
14
  * ```ts
21
- * // vite.config.ts
22
- * import vue from '@vitejs/plugin-vue'
23
15
  * import { Unhead } from '@unhead/vue/vite'
24
- *
25
- * export default defineConfig({
26
- * plugins: [vue(), Unhead()],
27
- * })
16
+ * export default defineConfig({ plugins: [...Unhead({ streaming: true })] })
28
17
  * ```
29
18
  */
30
- declare function Unhead(options?: UnheadVueViteOptions): Plugin[];
19
+ declare function Unhead(options?: UnheadVueOptions): Plugin[];
31
20
 
32
21
  export { Unhead };
33
22
  export type { UnheadVueViteOptions };
package/dist/vite.d.ts CHANGED
@@ -1,33 +1,22 @@
1
- import { VitePluginOptions } from '@unhead/bundler/vite';
2
- import { StreamingPluginOptions } from 'unhead/stream/vite';
3
1
  import { Plugin } from 'vite';
2
+ import { UnheadVueOptions } from './bundler.js';
3
+ import '@unhead/bundler/framework';
4
+ import './shared/vue.B_EhRTsW.js';
5
+ import 'unplugin';
6
+ import 'unhead/stream/unplugin';
4
7
 
5
- interface UnheadVueViteOptions extends VitePluginOptions {
6
- /**
7
- * Enable streaming SSR support.
8
- * Set to `true` or a config object to enable.
9
- * @default false
10
- */
11
- streaming?: true | Pick<StreamingPluginOptions, 'mode'> | false;
12
- }
8
+ type UnheadVueViteOptions = UnheadVueOptions;
13
9
  /**
14
- * Unified Vite plugin for `@unhead/vue`.
15
- *
16
- * Combines build optimizations (tree-shaking, useSeoMeta transform, minification)
17
- * with streaming SSR support into a single plugin.
10
+ * Vite plugin for `@unhead/vue`. Kept for backwards compatibility; prefer
11
+ * the unified `@unhead/vue/bundler` entry which dispatches to all bundlers.
18
12
  *
19
13
  * @example
20
14
  * ```ts
21
- * // vite.config.ts
22
- * import vue from '@vitejs/plugin-vue'
23
15
  * import { Unhead } from '@unhead/vue/vite'
24
- *
25
- * export default defineConfig({
26
- * plugins: [vue(), Unhead()],
27
- * })
16
+ * export default defineConfig({ plugins: [...Unhead({ streaming: true })] })
28
17
  * ```
29
18
  */
30
- declare function Unhead(options?: UnheadVueViteOptions): Plugin[];
19
+ declare function Unhead(options?: UnheadVueOptions): Plugin[];
31
20
 
32
21
  export { Unhead };
33
22
  export type { UnheadVueViteOptions };
package/dist/vite.mjs CHANGED
@@ -1,16 +1,11 @@
1
- import { Unhead as Unhead$1 } from '@unhead/bundler/vite';
2
- import unheadVuePlugin from './stream/vite.mjs';
3
- import 'magic-string';
4
- import 'oxc-walker';
5
- import 'unhead/stream/vite';
1
+ import { Unhead as Unhead$1 } from './bundler.mjs';
2
+ import '@unhead/bundler/framework';
3
+ import './shared/vue.D3FlIlye.mjs';
4
+ import 'unhead/stream/unplugin';
5
+ import 'unplugin';
6
6
 
7
7
  function Unhead(options = {}) {
8
- const plugins = [...Unhead$1({ ...options, _framework: "@unhead/vue" })];
9
- if (options.streaming) {
10
- const streamingOpts = typeof options.streaming === "object" ? options.streaming : void 0;
11
- plugins.push(unheadVuePlugin(streamingOpts));
12
- }
13
- return plugins;
8
+ return Unhead$1(options).vite();
14
9
  }
15
10
 
16
11
  export { Unhead };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unhead/vue",
3
3
  "type": "module",
4
- "version": "3.0.4",
4
+ "version": "3.1.0",
5
5
  "description": "Full-stack <head> manager built for Vue.",
6
6
  "author": "Harlan Wilton <harlan@harlanzw.com>",
7
7
  "license": "MIT",
@@ -61,6 +61,10 @@
61
61
  "types": "./dist/scripts.d.ts",
62
62
  "default": "./dist/scripts.mjs"
63
63
  },
64
+ "./bundler": {
65
+ "types": "./dist/bundler.d.ts",
66
+ "default": "./dist/bundler.mjs"
67
+ },
64
68
  "./vite": {
65
69
  "types": "./dist/vite.d.ts",
66
70
  "default": "./dist/vite.mjs"
@@ -110,6 +114,9 @@
110
114
  "scripts": [
111
115
  "dist/scripts"
112
116
  ],
117
+ "bundler": [
118
+ "dist/bundler"
119
+ ],
113
120
  "vite": [
114
121
  "dist/vite"
115
122
  ],
@@ -130,11 +137,15 @@
130
137
  ],
131
138
  "peerDependencies": {
132
139
  "vite": ">=6.4.2",
133
- "vue": ">=3.5.18"
140
+ "vue": ">=3.5.18",
141
+ "webpack": ">=5.0.0"
134
142
  },
135
143
  "peerDependenciesMeta": {
136
144
  "vite": {
137
145
  "optional": true
146
+ },
147
+ "webpack": {
148
+ "optional": true
138
149
  }
139
150
  },
140
151
  "build": {
@@ -143,17 +154,15 @@
143
154
  ]
144
155
  },
145
156
  "dependencies": {
146
- "hookable": "^6.1.0",
147
- "magic-string": "^0.30.21",
148
- "oxc-parser": "^0.125.0",
149
- "oxc-walker": "^0.7.0",
150
- "@unhead/bundler": "3.0.4",
151
- "unhead": "3.0.4"
157
+ "hookable": "^6.1.1",
158
+ "unplugin": "^3.0.0",
159
+ "@unhead/bundler": "3.1.0",
160
+ "unhead": "3.1.0"
152
161
  },
153
162
  "devDependencies": {
154
- "@vue/server-renderer": "^3.5.32",
155
- "vite": "^8.0.8",
156
- "vue": "^3.5.32"
163
+ "@vue/server-renderer": "^3.5.33",
164
+ "vite": "^8.0.10",
165
+ "vue": "^3.5.33"
157
166
  },
158
167
  "scripts": {
159
168
  "build": "unbuild",