@unhead/vue 0.2.0 → 0.2.3

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 CHANGED
@@ -47,20 +47,151 @@ const VueReactiveInputPlugin = () => {
47
47
  });
48
48
  };
49
49
 
50
- const Vue3 = vue.version.startsWith("3");
51
- vue.version.startsWith("2.");
52
- const IsBrowser = typeof window !== "undefined";
50
+ function unpackToArray(input, options) {
51
+ const unpacked = [];
52
+ const kFn = options.resolveKeyData || ((ctx) => ctx.key);
53
+ const vFn = options.resolveValueData || ((ctx) => ctx.value);
54
+ for (const [k, v] of Object.entries(input)) {
55
+ unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => {
56
+ const ctx = { key: k, value: i };
57
+ const val = vFn(ctx);
58
+ if (typeof val === "object")
59
+ return unpackToArray(val, options);
60
+ if (Array.isArray(val))
61
+ return val;
62
+ return {
63
+ [typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx),
64
+ [typeof options.value === "function" ? options.value(ctx) : options.value]: val
65
+ };
66
+ }).flat());
67
+ }
68
+ return unpacked;
69
+ }
53
70
 
54
- function useHead$2(input, options = {}) {
55
- const head = injectHead();
56
- head.push(input, options);
71
+ function unpackToString(value, options) {
72
+ return Object.entries(value).map(([key, value2]) => {
73
+ if (typeof value2 === "object")
74
+ value2 = unpackToString(value2, options);
75
+ if (options.resolve) {
76
+ const resolved = options.resolve({ key, value: value2 });
77
+ if (resolved)
78
+ return resolved;
79
+ }
80
+ if (typeof value2 === "number")
81
+ value2 = value2.toString();
82
+ if (typeof value2 === "string" && options.wrapValue) {
83
+ value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`);
84
+ value2 = `${options.wrapValue}${value2}${options.wrapValue}`;
85
+ }
86
+ return `${key}${options.keyValueSeparator || ""}${value2}`;
87
+ }).join(options.entrySeparator || "");
57
88
  }
58
89
 
59
- function useServerHead$1(input, options = {}) {
60
- useHead$2(input, { ...options, mode: "server" });
90
+ const MetaPackingSchema = {
91
+ robots: {
92
+ unpack: {
93
+ keyValueSeparator: ":"
94
+ }
95
+ },
96
+ contentSecurityPolicy: {
97
+ unpack: {
98
+ keyValueSeparator: " ",
99
+ entrySeparator: "; "
100
+ },
101
+ metaKey: "http-equiv"
102
+ },
103
+ fbAppId: {
104
+ keyValue: "fb:app_id",
105
+ metaKey: "property"
106
+ },
107
+ msapplicationTileImage: {
108
+ keyValue: "msapplication-TileImage"
109
+ },
110
+ msapplicationTileColor: {
111
+ keyValue: "msapplication-TileColor"
112
+ },
113
+ msapplicationConfig: {
114
+ keyValue: "msapplication-Config"
115
+ },
116
+ charset: {
117
+ metaKey: "charset"
118
+ },
119
+ contentType: {
120
+ metaKey: "http-equiv"
121
+ },
122
+ defaultStyle: {
123
+ metaKey: "http-equiv"
124
+ },
125
+ xUaCompatible: {
126
+ metaKey: "http-equiv"
127
+ },
128
+ refresh: {
129
+ metaKey: "http-equiv"
130
+ }
131
+ };
132
+ function resolveMetaKeyType(key) {
133
+ return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
61
134
  }
62
135
 
63
- function useHead$1(input, options = {}) {
136
+ function unpackMeta(input) {
137
+ return unpackToArray(input, {
138
+ key({ key }) {
139
+ return resolveMetaKeyType(key);
140
+ },
141
+ value({ key }) {
142
+ return key === "charset" ? "charset" : "content";
143
+ },
144
+ resolveKeyData({ key }) {
145
+ return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
146
+ },
147
+ resolveValueData({ value, key }) {
148
+ if (typeof value === "object") {
149
+ const definition = MetaPackingSchema[key];
150
+ if (key === "refresh")
151
+ return `${value.seconds};url=${value.url}`;
152
+ return unpackToString(
153
+ changeKeyCasingDeep(value),
154
+ {
155
+ entrySeparator: ", ",
156
+ keyValueSeparator: "=",
157
+ resolve({ value: value2, key: key2 }) {
158
+ if (typeof value2 === "boolean")
159
+ return `${key2}`;
160
+ },
161
+ ...definition?.unpack
162
+ }
163
+ );
164
+ }
165
+ return typeof value === "number" ? value.toString() : value;
166
+ }
167
+ });
168
+ }
169
+
170
+ const PropertyPrefixKeys = /^(og|twitter|fb)/;
171
+ function fixKeyCase(key) {
172
+ key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
173
+ if (PropertyPrefixKeys.test(key)) {
174
+ key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
175
+ }
176
+ return key;
177
+ }
178
+ function changeKeyCasingDeep(input) {
179
+ if (Array.isArray(input)) {
180
+ return input.map((entry) => changeKeyCasingDeep(entry));
181
+ }
182
+ if (typeof input !== "object" || Array.isArray(input))
183
+ return input;
184
+ const output = {};
185
+ for (const [key, value] of Object.entries(input))
186
+ output[fixKeyCase(key)] = changeKeyCasingDeep(value);
187
+ return output;
188
+ }
189
+
190
+ const Vue3 = vue.version.startsWith("3");
191
+ vue.version.startsWith("2.");
192
+ const IsBrowser = typeof window !== "undefined";
193
+
194
+ function clientUseHead(input, options = {}) {
64
195
  const head = injectHead();
65
196
  const vm = vue.getCurrentInstance();
66
197
  if (!vm) {
@@ -83,27 +214,56 @@ function useHead$1(input, options = {}) {
83
214
  });
84
215
  }
85
216
 
217
+ function serverUseHead(input, options = {}) {
218
+ const head = injectHead();
219
+ head.push(input, options);
220
+ }
221
+
86
222
  function useServerHead(input, options = {}) {
87
- if (!IsBrowser)
88
- useServerHead$1(input, options);
223
+ useHead(input, { ...options, mode: "server" });
89
224
  }
225
+ const useServerTagTitle = (title) => useServerHead({ title });
226
+ const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
227
+ const useServerTagMeta = (meta) => useServerHead({ meta: asArray(meta) });
228
+ const useServerTagMetaFlat = (meta) => {
229
+ const input = vue.ref({});
230
+ vue.watchEffect(() => {
231
+ input.value = unpackMeta(resolveUnrefHeadInput(meta));
232
+ });
233
+ return useServerHead({ meta: input });
234
+ };
235
+ const useServerTagLink = (link) => useServerHead({ link: asArray(link) });
236
+ const useServerTagScript = (script) => useServerHead({ script: asArray(script) });
237
+ const useServerTagStyle = (style) => useServerHead({ style: asArray(style) });
238
+ const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray(noscript) });
239
+ const useServerTagBase = (base) => useServerHead({ base });
240
+ const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
241
+ const useServerBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
242
+
90
243
  function useHead(input, options = {}) {
91
244
  if (options.mode === "server" && IsBrowser || options.mode === "client" && !IsBrowser)
92
245
  return;
93
- IsBrowser ? useHead$1(input, options) : useHead$2(input, options);
246
+ IsBrowser ? clientUseHead(input, options) : serverUseHead(input, options);
94
247
  }
95
- const useTitle = (title) => useHead({ title });
248
+ const useTagTitle = (title) => useHead({ title });
96
249
  const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
97
- const useMeta = (meta) => useHead({ meta: asArray(meta) });
98
- const useLink = (link) => useHead({ link: asArray(link) });
99
- const useScript = (script) => useHead({ script: asArray(script) });
100
- const useStyle = (style) => useHead({ style: asArray(style) });
101
- const useNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
102
- const useBase = (base) => useHead({ base });
250
+ const useTagMeta = (meta) => useHead({ meta: asArray(meta) });
251
+ const useTagMetaFlat = (meta) => {
252
+ const input = vue.ref({});
253
+ vue.watchEffect(() => {
254
+ input.value = unpackMeta(resolveUnrefHeadInput(meta));
255
+ });
256
+ return useHead({ meta: input });
257
+ };
258
+ const useTagLink = (link) => useHead({ link: asArray(link) });
259
+ const useTagScript = (script) => useHead({ script: asArray(script) });
260
+ const useTagStyle = (style) => useHead({ style: asArray(style) });
261
+ const useTagNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
262
+ const useTagBase = (base) => useHead({ base });
103
263
  const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
104
264
  const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
105
265
 
106
- const headSymbol = Symbol("unhead");
266
+ const headSymbol = "usehead";
107
267
  function injectHead() {
108
268
  return vue.getCurrentInstance() && vue.inject(headSymbol) || unhead.getActiveHead();
109
269
  }
@@ -184,17 +344,29 @@ exports.createHead = createHead;
184
344
  exports.headSymbol = headSymbol;
185
345
  exports.injectHead = injectHead;
186
346
  exports.resolveUnrefHeadInput = resolveUnrefHeadInput;
187
- exports.useBase = useBase;
188
347
  exports.useBodyAttrs = useBodyAttrs;
189
348
  exports.useHead = useHead;
190
349
  exports.useHtmlAttrs = useHtmlAttrs;
191
- exports.useLink = useLink;
192
- exports.useMeta = useMeta;
193
- exports.useNoscript = useNoscript;
194
- exports.useScript = useScript;
350
+ exports.useServerBodyAttrs = useServerBodyAttrs;
195
351
  exports.useServerHead = useServerHead;
196
- exports.useStyle = useStyle;
197
- exports.useTitle = useTitle;
352
+ exports.useServerHtmlAttrs = useServerHtmlAttrs;
353
+ exports.useServerTagBase = useServerTagBase;
354
+ exports.useServerTagLink = useServerTagLink;
355
+ exports.useServerTagMeta = useServerTagMeta;
356
+ exports.useServerTagMetaFlat = useServerTagMetaFlat;
357
+ exports.useServerTagNoscript = useServerTagNoscript;
358
+ exports.useServerTagScript = useServerTagScript;
359
+ exports.useServerTagStyle = useServerTagStyle;
360
+ exports.useServerTagTitle = useServerTagTitle;
361
+ exports.useServerTitleTemplate = useServerTitleTemplate;
362
+ exports.useTagBase = useTagBase;
363
+ exports.useTagLink = useTagLink;
364
+ exports.useTagMeta = useTagMeta;
365
+ exports.useTagMetaFlat = useTagMetaFlat;
366
+ exports.useTagNoscript = useTagNoscript;
367
+ exports.useTagScript = useTagScript;
368
+ exports.useTagStyle = useTagStyle;
369
+ exports.useTagTitle = useTagTitle;
198
370
  exports.useTitleTemplate = useTitleTemplate;
199
371
  for (const k in dom) {
200
372
  if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = dom[k];
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { MaybeComputedRef, MaybeRef } from '@vueuse/shared';
2
2
  export { MaybeComputedRef } from '@vueuse/shared';
3
3
  import * as _unhead_schema from '@unhead/schema';
4
- 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
+ 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, MetaFlatInput, HeadClient, CreateHeadOptions } from '@unhead/schema';
5
5
  export { ActiveHeadEntry, Head, HeadClient, HeadEntryOptions, HeadTag, MergeHead } from '@unhead/schema';
6
6
  import { RenderDomHeadOptions } from '@unhead/dom';
7
7
  export * from '@unhead/dom';
@@ -114,20 +114,33 @@ declare const VueTriggerDomPatchingOnUpdatesPlugin: (options?: RenderDomHeadOpti
114
114
  declare const VueReactiveInputPlugin: () => _unhead_schema.HeadPlugin;
115
115
 
116
116
  declare function useServerHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
117
+ declare const useServerTagTitle: (title: ReactiveHead['title']) => void;
118
+ declare const useServerTitleTemplate: (titleTemplate: ReactiveHead['titleTemplate']) => void;
119
+ declare const useServerTagMeta: (meta: Arrayable<Meta>) => void;
120
+ declare const useServerTagMetaFlat: (meta: MaybeComputedRefEntries<MetaFlatInput>) => void;
121
+ declare const useServerTagLink: (link: Arrayable<Link>) => void;
122
+ declare const useServerTagScript: (script: Arrayable<Script>) => void;
123
+ declare const useServerTagStyle: (style: Arrayable<Style>) => void;
124
+ declare const useServerTagNoscript: (noscript: Arrayable<Noscript>) => void;
125
+ declare const useServerTagBase: (base: ReactiveHead['base']) => void;
126
+ declare const useServerHtmlAttrs: (attrs: ReactiveHead['htmlAttrs']) => void;
127
+ declare const useServerBodyAttrs: (attrs: ReactiveHead['bodyAttrs']) => void;
128
+
117
129
  declare function useHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
118
- declare const useTitle: (title: ReactiveHead['title']) => void;
130
+ declare const useTagTitle: (title: ReactiveHead['title']) => void;
119
131
  declare const useTitleTemplate: (titleTemplate: ReactiveHead['titleTemplate']) => void;
120
- declare const useMeta: (meta: Arrayable<Meta>) => void;
121
- declare const useLink: (link: Arrayable<Link>) => void;
122
- declare const useScript: (script: Arrayable<Script>) => void;
123
- declare const useStyle: (style: Arrayable<Style>) => void;
124
- declare const useNoscript: (noscript: Arrayable<Noscript>) => void;
125
- declare const useBase: (base: ReactiveHead['base']) => void;
132
+ declare const useTagMeta: (meta: Arrayable<Meta>) => void;
133
+ declare const useTagMetaFlat: (meta: MaybeComputedRefEntries<MetaFlatInput>) => void;
134
+ declare const useTagLink: (link: Arrayable<Link>) => void;
135
+ declare const useTagScript: (script: Arrayable<Script>) => void;
136
+ declare const useTagStyle: (style: Arrayable<Style>) => void;
137
+ declare const useTagNoscript: (noscript: Arrayable<Noscript>) => void;
138
+ declare const useTagBase: (base: ReactiveHead['base']) => void;
126
139
  declare const useHtmlAttrs: (attrs: ReactiveHead['htmlAttrs']) => void;
127
140
  declare const useBodyAttrs: (attrs: ReactiveHead['bodyAttrs']) => void;
128
141
 
129
142
  declare type VueHeadClient<T extends MergeHead> = HeadClient<MaybeComputedRef<ReactiveHead<T>>> & Plugin;
130
- declare const headSymbol: unique symbol;
143
+ declare const headSymbol = "usehead";
131
144
  declare function injectHead<T extends MergeHead>(): VueHeadClient<T>;
132
145
  declare function createHead<T extends MergeHead>(options?: CreateHeadOptions): VueHeadClient<T>;
133
146
 
@@ -137,4 +150,4 @@ declare function createDomHead<T extends MergeHead>(options?: CreateHeadOptions
137
150
 
138
151
  declare const HeadVuePlugin: Plugin;
139
152
 
140
- export { Arrayable, Base, BodyAttributes, HeadVuePlugin, HtmlAttributes, Link, MaybeComputedRefEntries, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, VueHeadClient, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
153
+ export { Arrayable, Base, BodyAttributes, HeadVuePlugin, HtmlAttributes, Link, MaybeComputedRefEntries, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, VueHeadClient, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
package/dist/index.mjs CHANGED
@@ -46,20 +46,151 @@ const VueReactiveInputPlugin = () => {
46
46
  });
47
47
  };
48
48
 
49
- const Vue3 = version.startsWith("3");
50
- version.startsWith("2.");
51
- const IsBrowser = typeof window !== "undefined";
49
+ function unpackToArray(input, options) {
50
+ const unpacked = [];
51
+ const kFn = options.resolveKeyData || ((ctx) => ctx.key);
52
+ const vFn = options.resolveValueData || ((ctx) => ctx.value);
53
+ for (const [k, v] of Object.entries(input)) {
54
+ unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => {
55
+ const ctx = { key: k, value: i };
56
+ const val = vFn(ctx);
57
+ if (typeof val === "object")
58
+ return unpackToArray(val, options);
59
+ if (Array.isArray(val))
60
+ return val;
61
+ return {
62
+ [typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx),
63
+ [typeof options.value === "function" ? options.value(ctx) : options.value]: val
64
+ };
65
+ }).flat());
66
+ }
67
+ return unpacked;
68
+ }
52
69
 
53
- function useHead$2(input, options = {}) {
54
- const head = injectHead();
55
- head.push(input, options);
70
+ function unpackToString(value, options) {
71
+ return Object.entries(value).map(([key, value2]) => {
72
+ if (typeof value2 === "object")
73
+ value2 = unpackToString(value2, options);
74
+ if (options.resolve) {
75
+ const resolved = options.resolve({ key, value: value2 });
76
+ if (resolved)
77
+ return resolved;
78
+ }
79
+ if (typeof value2 === "number")
80
+ value2 = value2.toString();
81
+ if (typeof value2 === "string" && options.wrapValue) {
82
+ value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`);
83
+ value2 = `${options.wrapValue}${value2}${options.wrapValue}`;
84
+ }
85
+ return `${key}${options.keyValueSeparator || ""}${value2}`;
86
+ }).join(options.entrySeparator || "");
56
87
  }
57
88
 
58
- function useServerHead$1(input, options = {}) {
59
- useHead$2(input, { ...options, mode: "server" });
89
+ const MetaPackingSchema = {
90
+ robots: {
91
+ unpack: {
92
+ keyValueSeparator: ":"
93
+ }
94
+ },
95
+ contentSecurityPolicy: {
96
+ unpack: {
97
+ keyValueSeparator: " ",
98
+ entrySeparator: "; "
99
+ },
100
+ metaKey: "http-equiv"
101
+ },
102
+ fbAppId: {
103
+ keyValue: "fb:app_id",
104
+ metaKey: "property"
105
+ },
106
+ msapplicationTileImage: {
107
+ keyValue: "msapplication-TileImage"
108
+ },
109
+ msapplicationTileColor: {
110
+ keyValue: "msapplication-TileColor"
111
+ },
112
+ msapplicationConfig: {
113
+ keyValue: "msapplication-Config"
114
+ },
115
+ charset: {
116
+ metaKey: "charset"
117
+ },
118
+ contentType: {
119
+ metaKey: "http-equiv"
120
+ },
121
+ defaultStyle: {
122
+ metaKey: "http-equiv"
123
+ },
124
+ xUaCompatible: {
125
+ metaKey: "http-equiv"
126
+ },
127
+ refresh: {
128
+ metaKey: "http-equiv"
129
+ }
130
+ };
131
+ function resolveMetaKeyType(key) {
132
+ return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
60
133
  }
61
134
 
62
- function useHead$1(input, options = {}) {
135
+ function unpackMeta(input) {
136
+ return unpackToArray(input, {
137
+ key({ key }) {
138
+ return resolveMetaKeyType(key);
139
+ },
140
+ value({ key }) {
141
+ return key === "charset" ? "charset" : "content";
142
+ },
143
+ resolveKeyData({ key }) {
144
+ return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
145
+ },
146
+ resolveValueData({ value, key }) {
147
+ if (typeof value === "object") {
148
+ const definition = MetaPackingSchema[key];
149
+ if (key === "refresh")
150
+ return `${value.seconds};url=${value.url}`;
151
+ return unpackToString(
152
+ changeKeyCasingDeep(value),
153
+ {
154
+ entrySeparator: ", ",
155
+ keyValueSeparator: "=",
156
+ resolve({ value: value2, key: key2 }) {
157
+ if (typeof value2 === "boolean")
158
+ return `${key2}`;
159
+ },
160
+ ...definition?.unpack
161
+ }
162
+ );
163
+ }
164
+ return typeof value === "number" ? value.toString() : value;
165
+ }
166
+ });
167
+ }
168
+
169
+ const PropertyPrefixKeys = /^(og|twitter|fb)/;
170
+ function fixKeyCase(key) {
171
+ key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
172
+ if (PropertyPrefixKeys.test(key)) {
173
+ key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
174
+ }
175
+ return key;
176
+ }
177
+ function changeKeyCasingDeep(input) {
178
+ if (Array.isArray(input)) {
179
+ return input.map((entry) => changeKeyCasingDeep(entry));
180
+ }
181
+ if (typeof input !== "object" || Array.isArray(input))
182
+ return input;
183
+ const output = {};
184
+ for (const [key, value] of Object.entries(input))
185
+ output[fixKeyCase(key)] = changeKeyCasingDeep(value);
186
+ return output;
187
+ }
188
+
189
+ const Vue3 = version.startsWith("3");
190
+ version.startsWith("2.");
191
+ const IsBrowser = typeof window !== "undefined";
192
+
193
+ function clientUseHead(input, options = {}) {
63
194
  const head = injectHead();
64
195
  const vm = getCurrentInstance();
65
196
  if (!vm) {
@@ -82,27 +213,56 @@ function useHead$1(input, options = {}) {
82
213
  });
83
214
  }
84
215
 
216
+ function serverUseHead(input, options = {}) {
217
+ const head = injectHead();
218
+ head.push(input, options);
219
+ }
220
+
85
221
  function useServerHead(input, options = {}) {
86
- if (!IsBrowser)
87
- useServerHead$1(input, options);
222
+ useHead(input, { ...options, mode: "server" });
88
223
  }
224
+ const useServerTagTitle = (title) => useServerHead({ title });
225
+ const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
226
+ const useServerTagMeta = (meta) => useServerHead({ meta: asArray(meta) });
227
+ const useServerTagMetaFlat = (meta) => {
228
+ const input = ref({});
229
+ watchEffect(() => {
230
+ input.value = unpackMeta(resolveUnrefHeadInput(meta));
231
+ });
232
+ return useServerHead({ meta: input });
233
+ };
234
+ const useServerTagLink = (link) => useServerHead({ link: asArray(link) });
235
+ const useServerTagScript = (script) => useServerHead({ script: asArray(script) });
236
+ const useServerTagStyle = (style) => useServerHead({ style: asArray(style) });
237
+ const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray(noscript) });
238
+ const useServerTagBase = (base) => useServerHead({ base });
239
+ const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
240
+ const useServerBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
241
+
89
242
  function useHead(input, options = {}) {
90
243
  if (options.mode === "server" && IsBrowser || options.mode === "client" && !IsBrowser)
91
244
  return;
92
- IsBrowser ? useHead$1(input, options) : useHead$2(input, options);
245
+ IsBrowser ? clientUseHead(input, options) : serverUseHead(input, options);
93
246
  }
94
- const useTitle = (title) => useHead({ title });
247
+ const useTagTitle = (title) => useHead({ title });
95
248
  const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
96
- const useMeta = (meta) => useHead({ meta: asArray(meta) });
97
- const useLink = (link) => useHead({ link: asArray(link) });
98
- const useScript = (script) => useHead({ script: asArray(script) });
99
- const useStyle = (style) => useHead({ style: asArray(style) });
100
- const useNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
101
- const useBase = (base) => useHead({ base });
249
+ const useTagMeta = (meta) => useHead({ meta: asArray(meta) });
250
+ const useTagMetaFlat = (meta) => {
251
+ const input = ref({});
252
+ watchEffect(() => {
253
+ input.value = unpackMeta(resolveUnrefHeadInput(meta));
254
+ });
255
+ return useHead({ meta: input });
256
+ };
257
+ const useTagLink = (link) => useHead({ link: asArray(link) });
258
+ const useTagScript = (script) => useHead({ script: asArray(script) });
259
+ const useTagStyle = (style) => useHead({ style: asArray(style) });
260
+ const useTagNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
261
+ const useTagBase = (base) => useHead({ base });
102
262
  const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
103
263
  const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
104
264
 
105
- const headSymbol = Symbol("unhead");
265
+ const headSymbol = "usehead";
106
266
  function injectHead() {
107
267
  return getCurrentInstance() && inject(headSymbol) || getActiveHead();
108
268
  }
@@ -174,4 +334,4 @@ const HeadVuePlugin = function(_Vue) {
174
334
  });
175
335
  };
176
336
 
177
- export { HeadVuePlugin, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
337
+ export { HeadVuePlugin, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unhead/vue",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.2.3",
5
5
  "packageManager": "pnpm@7.14.0",
6
6
  "author": "Harlan Wilton <harlan@harlanzw.com>",
7
7
  "license": "MIT",
@@ -33,10 +33,10 @@
33
33
  "vue": ">=2.7 || >=3"
34
34
  },
35
35
  "dependencies": {
36
- "@unhead/dom": "0.2.0",
37
- "@unhead/schema": "0.2.0",
36
+ "@unhead/dom": "0.2.3",
37
+ "@unhead/schema": "0.2.3",
38
38
  "@vueuse/shared": "latest",
39
- "unhead": "0.2.0"
39
+ "unhead": "0.2.3"
40
40
  },
41
41
  "devDependencies": {
42
42
  "vue": "latest"
@@ -1,2 +0,0 @@
1
- export * from './useHead';
2
- export * from './useServerHead';
@@ -1,2 +0,0 @@
1
- export * from "./useHead.mjs";
2
- export * from "./useServerHead.mjs";
@@ -1,3 +0,0 @@
1
- import type { HeadEntryOptions, MergeHead } from '@unhead/schema';
2
- import type { UseHeadInput } from '../..';
3
- export declare function useHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
@@ -1,5 +0,0 @@
1
- import { injectHead } from "../..";
2
- export function useHead(input, options = {}) {
3
- const head = injectHead();
4
- head.push(input, options);
5
- }
@@ -1,3 +0,0 @@
1
- import type { HeadEntryOptions, MergeHead } from '@unhead/schema';
2
- import type { UseHeadInput } from '../../types';
3
- export declare function useServerHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
@@ -1,4 +0,0 @@
1
- import { useHead } from "./index.mjs";
2
- export function useServerHead(input, options = {}) {
3
- useHead(input, { ...options, mode: "server" });
4
- }
@@ -1,2 +0,0 @@
1
- export * from './useHead';
2
- export * from './useServerHead';
@@ -1,2 +0,0 @@
1
- export * from "./useHead.mjs";
2
- export * from "./useServerHead.mjs";
@@ -1,3 +0,0 @@
1
- import type { HeadEntryOptions, MergeHead } from '@unhead/schema';
2
- import type { UseHeadInput } from '../../index';
3
- export declare function useHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
@@ -1,24 +0,0 @@
1
- import { getCurrentInstance, onBeforeUnmount, ref, watch, watchEffect } from "vue";
2
- import { injectHead, resolveUnrefHeadInput } from "../../index";
3
- export function useHead(input, options = {}) {
4
- const head = injectHead();
5
- const vm = getCurrentInstance();
6
- if (!vm) {
7
- head.push(input, options);
8
- return;
9
- }
10
- const resolvedInput = ref({});
11
- watchEffect(() => {
12
- resolvedInput.value = resolveUnrefHeadInput(input);
13
- });
14
- let entry;
15
- watch(resolvedInput, (e) => {
16
- if (!entry)
17
- entry = head.push(e, options);
18
- else
19
- entry.patch(e);
20
- }, { immediate: true });
21
- onBeforeUnmount(() => {
22
- entry?.dispose();
23
- });
24
- }
@@ -1,3 +0,0 @@
1
- import type { HeadEntryOptions, MergeHead } from '@unhead/schema';
2
- import type { UseHeadInput } from '../../types';
3
- export declare function useServerHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
@@ -1,2 +0,0 @@
1
- export function useServerHead(input, options = {}) {
2
- }