@unhead/vue 0.1.0 → 0.1.2
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.
- package/dist/index.cjs +196 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.mjs +31 -14
- package/dist/runtimes/client/useHead.mjs +1 -4
- package/package.json +4 -4
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const shared = require('@vueuse/shared');
|
|
4
|
+
const vue = require('vue');
|
|
5
|
+
const unhead = require('unhead');
|
|
6
|
+
const dom = require('@unhead/dom');
|
|
7
|
+
|
|
8
|
+
function resolveUnrefHeadInput(ref) {
|
|
9
|
+
const root = shared.resolveUnref(ref);
|
|
10
|
+
if (!ref || !root)
|
|
11
|
+
return root;
|
|
12
|
+
if (Array.isArray(root))
|
|
13
|
+
return root.map(resolveUnrefHeadInput);
|
|
14
|
+
if (typeof root === "object") {
|
|
15
|
+
return Object.fromEntries(
|
|
16
|
+
Object.entries(root).map(([key, value]) => {
|
|
17
|
+
if (key === "titleTemplate")
|
|
18
|
+
return [key, vue.unref(value)];
|
|
19
|
+
return [key, resolveUnrefHeadInput(value)];
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
return root;
|
|
24
|
+
}
|
|
25
|
+
function asArray(value) {
|
|
26
|
+
return Array.isArray(value) ? value : [value];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const VueTriggerDomPatchingOnUpdatesPlugin = () => {
|
|
30
|
+
return unhead.defineHeadPlugin({
|
|
31
|
+
hooks: {
|
|
32
|
+
"entries:updated": function(head) {
|
|
33
|
+
dom.debouncedRenderDOMHead(vue.nextTick, head);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const vueTriggerDomPatchingOnUpdatesPlugin = {
|
|
40
|
+
__proto__: null,
|
|
41
|
+
VueTriggerDomPatchingOnUpdatesPlugin: VueTriggerDomPatchingOnUpdatesPlugin
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const VueReactiveInputPlugin = () => {
|
|
45
|
+
return unhead.defineHeadPlugin({
|
|
46
|
+
hooks: {
|
|
47
|
+
"entries:resolve": function(ctx) {
|
|
48
|
+
for (const entry of ctx.entries)
|
|
49
|
+
entry.input = resolveUnrefHeadInput(entry.input);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const Vue3 = vue.version.startsWith("3");
|
|
56
|
+
vue.version.startsWith("2.");
|
|
57
|
+
const IsClient = typeof window !== "undefined";
|
|
58
|
+
|
|
59
|
+
function useHead$2(input, options = {}) {
|
|
60
|
+
const head = injectHead();
|
|
61
|
+
head.push(input, options);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function useServerHead$1(input, options = {}) {
|
|
65
|
+
useHead$2(input, { ...options, mode: "server" });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function useHead$1(input, options = {}) {
|
|
69
|
+
const head = injectHead();
|
|
70
|
+
const vm = vue.getCurrentInstance();
|
|
71
|
+
if (!vm) {
|
|
72
|
+
head.push(input, options);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const resolvedInput = vue.ref({});
|
|
76
|
+
vue.watchEffect(() => {
|
|
77
|
+
resolvedInput.value = resolveUnrefHeadInput(input);
|
|
78
|
+
});
|
|
79
|
+
let entry;
|
|
80
|
+
vue.watch(resolvedInput, (e) => {
|
|
81
|
+
if (!entry)
|
|
82
|
+
entry = head.push(e, options);
|
|
83
|
+
else
|
|
84
|
+
entry.patch(e);
|
|
85
|
+
}, { immediate: true });
|
|
86
|
+
vue.onBeforeUnmount(() => {
|
|
87
|
+
entry?.dispose();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function useServerHead(input, options = {}) {
|
|
92
|
+
if (!IsClient)
|
|
93
|
+
useServerHead$1(input, options);
|
|
94
|
+
}
|
|
95
|
+
function useHead(input, options = {}) {
|
|
96
|
+
if (options.mode === "server" && IsClient || options.mode === "client" && !IsClient)
|
|
97
|
+
return;
|
|
98
|
+
IsClient ? useHead$1(input, options) : useHead$2(input, options);
|
|
99
|
+
}
|
|
100
|
+
const useTitle = (title) => useHead({ title });
|
|
101
|
+
const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
|
|
102
|
+
const useMeta = (meta) => useHead({ meta: asArray(meta) });
|
|
103
|
+
const useLink = (link) => useHead({ link: asArray(link) });
|
|
104
|
+
const useScript = (script) => useHead({ script: asArray(script) });
|
|
105
|
+
const useStyle = (style) => useHead({ style: asArray(style) });
|
|
106
|
+
const useNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
|
|
107
|
+
const useBase = (base) => useHead({ base });
|
|
108
|
+
const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
|
|
109
|
+
const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
|
|
110
|
+
|
|
111
|
+
const headSymbol = Symbol("head");
|
|
112
|
+
function injectHead() {
|
|
113
|
+
return vue.getCurrentInstance() && vue.inject(headSymbol) || unhead.getActiveHead();
|
|
114
|
+
}
|
|
115
|
+
async function createHead(options = {}) {
|
|
116
|
+
const plugins = [
|
|
117
|
+
unhead.HydratesStatePlugin(),
|
|
118
|
+
VueReactiveInputPlugin(),
|
|
119
|
+
...options?.plugins || []
|
|
120
|
+
];
|
|
121
|
+
if (IsClient) {
|
|
122
|
+
const { VueTriggerDomPatchingOnUpdatesPlugin } = await Promise.resolve().then(function () { return vueTriggerDomPatchingOnUpdatesPlugin; });
|
|
123
|
+
plugins.push(VueTriggerDomPatchingOnUpdatesPlugin());
|
|
124
|
+
}
|
|
125
|
+
const head = await unhead.createHead({
|
|
126
|
+
...options,
|
|
127
|
+
plugins
|
|
128
|
+
});
|
|
129
|
+
const vuePlugin = {
|
|
130
|
+
install(app) {
|
|
131
|
+
if (Vue3)
|
|
132
|
+
app.config.globalProperties.$head = head;
|
|
133
|
+
app.provide(headSymbol, head);
|
|
134
|
+
app.mixin({
|
|
135
|
+
created() {
|
|
136
|
+
const instance = vue.getCurrentInstance();
|
|
137
|
+
if (!instance)
|
|
138
|
+
return;
|
|
139
|
+
const options2 = instance.type;
|
|
140
|
+
if (!options2 || !("head" in options2))
|
|
141
|
+
return;
|
|
142
|
+
const source = typeof options2.head === "function" ? () => options2.head() : options2.head;
|
|
143
|
+
head.push(source);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
return { ...vuePlugin, ...head };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const HeadVuePlugin = function(_Vue) {
|
|
152
|
+
_Vue.mixin({
|
|
153
|
+
beforeCreate() {
|
|
154
|
+
const options = this.$options;
|
|
155
|
+
if (options.head) {
|
|
156
|
+
const origProvide = options.provide;
|
|
157
|
+
options.provide = function() {
|
|
158
|
+
let origProvideResult;
|
|
159
|
+
if (typeof origProvide === "function")
|
|
160
|
+
origProvideResult = origProvide.call(this);
|
|
161
|
+
else
|
|
162
|
+
origProvideResult = origProvide || {};
|
|
163
|
+
return {
|
|
164
|
+
...origProvideResult,
|
|
165
|
+
[headSymbol]: options.head
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
if (!this.$head)
|
|
169
|
+
this.$head = options.head;
|
|
170
|
+
} else if (!this.$head && options.parent && options.parent.$head) {
|
|
171
|
+
this.$head = options.parent.$head;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
exports.HeadVuePlugin = HeadVuePlugin;
|
|
178
|
+
exports.VueReactiveInputPlugin = VueReactiveInputPlugin;
|
|
179
|
+
exports.VueTriggerDomPatchingOnUpdatesPlugin = VueTriggerDomPatchingOnUpdatesPlugin;
|
|
180
|
+
exports.asArray = asArray;
|
|
181
|
+
exports.createHead = createHead;
|
|
182
|
+
exports.headSymbol = headSymbol;
|
|
183
|
+
exports.injectHead = injectHead;
|
|
184
|
+
exports.resolveUnrefHeadInput = resolveUnrefHeadInput;
|
|
185
|
+
exports.useBase = useBase;
|
|
186
|
+
exports.useBodyAttrs = useBodyAttrs;
|
|
187
|
+
exports.useHead = useHead;
|
|
188
|
+
exports.useHtmlAttrs = useHtmlAttrs;
|
|
189
|
+
exports.useLink = useLink;
|
|
190
|
+
exports.useMeta = useMeta;
|
|
191
|
+
exports.useNoscript = useNoscript;
|
|
192
|
+
exports.useScript = useScript;
|
|
193
|
+
exports.useServerHead = useServerHead;
|
|
194
|
+
exports.useStyle = useStyle;
|
|
195
|
+
exports.useTitle = useTitle;
|
|
196
|
+
exports.useTitleTemplate = useTitleTemplate;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import * as _unhead_schema from '@unhead/schema';
|
|
|
3
3
|
import { Title as Title$1, TitleTemplate as TitleTemplate$1, EntryAugmentation, Base as Base$1, Link as Link$1, Meta as Meta$1, Style as Style$1, Script as Script$1, Noscript as Noscript$1, DataKeys, SchemaAugmentations, DefinedValueOrEmptyObject, MergeHead, BaseHtmlAttr, MaybeArray, BaseBodyAttr, HeadEntryOptions, HeadClient, CreateHeadOptions } from '@unhead/schema';
|
|
4
4
|
export { HeadTag, MergeHead } from '@unhead/schema';
|
|
5
5
|
import { Plugin, InjectionKey } from 'vue';
|
|
6
|
-
export * from '@unhead/dom';
|
|
7
6
|
|
|
8
7
|
declare type MaybeComputedRefEntries<T> = MaybeComputedRef<T> | {
|
|
9
8
|
[key in keyof T]?: MaybeComputedRef<T[key]>;
|
|
@@ -107,6 +106,8 @@ declare type UseHeadInput = MaybeComputedRef<ReactiveHead>;
|
|
|
107
106
|
declare function resolveUnrefHeadInput(ref: any): any;
|
|
108
107
|
declare function asArray<T>(value: Arrayable<T>): T[];
|
|
109
108
|
|
|
109
|
+
declare const VueTriggerDomPatchingOnUpdatesPlugin: () => _unhead_schema.HeadPlugin;
|
|
110
|
+
|
|
110
111
|
declare const VueReactiveInputPlugin: () => _unhead_schema.HeadPlugin;
|
|
111
112
|
|
|
112
113
|
declare function useServerHead(input: ReactiveHead, options?: HeadEntryOptions): void;
|
|
@@ -125,8 +126,8 @@ declare const useBodyAttrs: (attrs: ReactiveHead['bodyAttrs']) => void;
|
|
|
125
126
|
declare type VueHeadClient = HeadClient<UseHeadInput> & Plugin;
|
|
126
127
|
declare const headSymbol: InjectionKey<VueHeadClient>;
|
|
127
128
|
declare function injectHead(): VueHeadClient;
|
|
128
|
-
declare function createHead(options?: CreateHeadOptions): VueHeadClient
|
|
129
|
+
declare function createHead(options?: CreateHeadOptions): Promise<VueHeadClient>;
|
|
129
130
|
|
|
130
131
|
declare const HeadVuePlugin: Plugin;
|
|
131
132
|
|
|
132
|
-
export { Arrayable, Base, BodyAttributes, HeadVuePlugin, HtmlAttributes, Link, MaybeComputedRefEntries, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, VueHeadClient, VueReactiveInputPlugin, asArray, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
|
|
133
|
+
export { Arrayable, Base, BodyAttributes, HeadVuePlugin, HtmlAttributes, Link, MaybeComputedRefEntries, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, VueHeadClient, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { resolveUnref } from '@vueuse/shared';
|
|
2
|
-
import { unref, version, getCurrentInstance, ref, watchEffect, watch,
|
|
3
|
-
import { defineHeadPlugin, getActiveHead, createHead as createHead$1
|
|
2
|
+
import { unref, nextTick, version, getCurrentInstance, ref, watchEffect, watch, onBeforeUnmount, inject } from 'vue';
|
|
3
|
+
import { defineHeadPlugin, getActiveHead, HydratesStatePlugin, createHead as createHead$1 } from 'unhead';
|
|
4
4
|
import { debouncedRenderDOMHead } from '@unhead/dom';
|
|
5
|
-
export * from '@unhead/dom';
|
|
6
5
|
|
|
7
6
|
function resolveUnrefHeadInput(ref) {
|
|
8
7
|
const root = resolveUnref(ref);
|
|
@@ -25,6 +24,21 @@ function asArray(value) {
|
|
|
25
24
|
return Array.isArray(value) ? value : [value];
|
|
26
25
|
}
|
|
27
26
|
|
|
27
|
+
const VueTriggerDomPatchingOnUpdatesPlugin = () => {
|
|
28
|
+
return defineHeadPlugin({
|
|
29
|
+
hooks: {
|
|
30
|
+
"entries:updated": function(head) {
|
|
31
|
+
debouncedRenderDOMHead(nextTick, head);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const vueTriggerDomPatchingOnUpdatesPlugin = {
|
|
38
|
+
__proto__: null,
|
|
39
|
+
VueTriggerDomPatchingOnUpdatesPlugin: VueTriggerDomPatchingOnUpdatesPlugin
|
|
40
|
+
};
|
|
41
|
+
|
|
28
42
|
const VueReactiveInputPlugin = () => {
|
|
29
43
|
return defineHeadPlugin({
|
|
30
44
|
hooks: {
|
|
@@ -66,11 +80,9 @@ function useHead$1(input, options = {}) {
|
|
|
66
80
|
entry = head.push(e, options);
|
|
67
81
|
else
|
|
68
82
|
entry.patch(e);
|
|
69
|
-
debouncedRenderDOMHead(nextTick, head);
|
|
70
83
|
}, { immediate: true });
|
|
71
84
|
onBeforeUnmount(() => {
|
|
72
85
|
entry?.dispose();
|
|
73
|
-
debouncedRenderDOMHead(nextTick, head);
|
|
74
86
|
});
|
|
75
87
|
}
|
|
76
88
|
|
|
@@ -81,7 +93,7 @@ function useServerHead(input, options = {}) {
|
|
|
81
93
|
function useHead(input, options = {}) {
|
|
82
94
|
if (options.mode === "server" && IsClient || options.mode === "client" && !IsClient)
|
|
83
95
|
return;
|
|
84
|
-
|
|
96
|
+
IsClient ? useHead$1(input, options) : useHead$2(input, options);
|
|
85
97
|
}
|
|
86
98
|
const useTitle = (title) => useHead({ title });
|
|
87
99
|
const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
|
|
@@ -98,14 +110,19 @@ const headSymbol = Symbol("head");
|
|
|
98
110
|
function injectHead() {
|
|
99
111
|
return getCurrentInstance() && inject(headSymbol) || getActiveHead();
|
|
100
112
|
}
|
|
101
|
-
function createHead(options = {}) {
|
|
102
|
-
const
|
|
113
|
+
async function createHead(options = {}) {
|
|
114
|
+
const plugins = [
|
|
115
|
+
HydratesStatePlugin(),
|
|
116
|
+
VueReactiveInputPlugin(),
|
|
117
|
+
...options?.plugins || []
|
|
118
|
+
];
|
|
119
|
+
if (IsClient) {
|
|
120
|
+
const { VueTriggerDomPatchingOnUpdatesPlugin } = await Promise.resolve().then(function () { return vueTriggerDomPatchingOnUpdatesPlugin; });
|
|
121
|
+
plugins.push(VueTriggerDomPatchingOnUpdatesPlugin());
|
|
122
|
+
}
|
|
123
|
+
const head = await createHead$1({
|
|
103
124
|
...options,
|
|
104
|
-
plugins
|
|
105
|
-
HydratesStatePlugin(),
|
|
106
|
-
VueReactiveInputPlugin(),
|
|
107
|
-
...options?.plugins || []
|
|
108
|
-
]
|
|
125
|
+
plugins
|
|
109
126
|
});
|
|
110
127
|
const vuePlugin = {
|
|
111
128
|
install(app) {
|
|
@@ -155,4 +172,4 @@ const HeadVuePlugin = function(_Vue) {
|
|
|
155
172
|
});
|
|
156
173
|
};
|
|
157
174
|
|
|
158
|
-
export { HeadVuePlugin, VueReactiveInputPlugin, asArray, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
|
|
175
|
+
export { HeadVuePlugin, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { getCurrentInstance,
|
|
2
|
-
import { debouncedRenderDOMHead } from "@unhead/dom";
|
|
1
|
+
import { getCurrentInstance, onBeforeUnmount, ref, watch, watchEffect } from "vue";
|
|
3
2
|
import { injectHead, resolveUnrefHeadInput } from "../../index";
|
|
4
3
|
export function useHead(input, options = {}) {
|
|
5
4
|
const head = injectHead();
|
|
@@ -18,10 +17,8 @@ export function useHead(input, options = {}) {
|
|
|
18
17
|
entry = head.push(e, options);
|
|
19
18
|
else
|
|
20
19
|
entry.patch(e);
|
|
21
|
-
debouncedRenderDOMHead(nextTick, head);
|
|
22
20
|
}, { immediate: true });
|
|
23
21
|
onBeforeUnmount(() => {
|
|
24
22
|
entry?.dispose();
|
|
25
|
-
debouncedRenderDOMHead(nextTick, head);
|
|
26
23
|
});
|
|
27
24
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unhead/vue",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"vue": ">=2.7 || >=3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@unhead/dom": "0.1.
|
|
35
|
-
"@unhead/schema": "0.1.
|
|
34
|
+
"@unhead/dom": "0.1.2",
|
|
35
|
+
"@unhead/schema": "0.1.2",
|
|
36
36
|
"@vueuse/shared": "latest",
|
|
37
|
-
"unhead": "0.1.
|
|
37
|
+
"unhead": "0.1.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"vue": "latest"
|