nuxt-seo-utils 7.0.13 → 7.0.15

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.
Files changed (34) hide show
  1. package/package.json +21 -21
  2. package/dist/module.d.mts +0 -115
  3. package/dist/module.json +0 -12
  4. package/dist/module.mjs +0 -547
  5. package/dist/runtime/app/composables/polyfills.d.ts +0 -11
  6. package/dist/runtime/app/composables/polyfills.js +0 -27
  7. package/dist/runtime/app/composables/useBreadcrumbItems.d.ts +0 -112
  8. package/dist/runtime/app/composables/useBreadcrumbItems.js +0 -196
  9. package/dist/runtime/app/logic/applyDefaults.d.ts +0 -1
  10. package/dist/runtime/app/logic/applyDefaults.js +0 -78
  11. package/dist/runtime/app/plugins/0.routeRules.d.ts +0 -2
  12. package/dist/runtime/app/plugins/0.routeRules.js +0 -24
  13. package/dist/runtime/app/plugins/1.absoluteImageUrls.server.d.ts +0 -2
  14. package/dist/runtime/app/plugins/1.absoluteImageUrls.server.js +0 -33
  15. package/dist/runtime/app/plugins/defaults.d.ts +0 -2
  16. package/dist/runtime/app/plugins/defaults.js +0 -12
  17. package/dist/runtime/app/plugins/defaultsWaitI18n.d.ts +0 -2
  18. package/dist/runtime/app/plugins/defaultsWaitI18n.js +0 -13
  19. package/dist/runtime/app/plugins/inferSeoMetaPlugin.d.ts +0 -2
  20. package/dist/runtime/app/plugins/inferSeoMetaPlugin.js +0 -11
  21. package/dist/runtime/app/plugins/siteConfig.d.ts +0 -2
  22. package/dist/runtime/app/plugins/siteConfig.js +0 -33
  23. package/dist/runtime/app/plugins/titles.d.ts +0 -2
  24. package/dist/runtime/app/plugins/titles.js +0 -30
  25. package/dist/runtime/server/middleware/redirectCanonical.d.ts +0 -2
  26. package/dist/runtime/server/middleware/redirectCanonical.js +0 -28
  27. package/dist/runtime/server/middleware/resolveImagesInPagesDir.d.ts +0 -2
  28. package/dist/runtime/server/middleware/resolveImagesInPagesDir.js +0 -16
  29. package/dist/runtime/server/tsconfig.json +0 -3
  30. package/dist/runtime/shared/breadcrumbs.d.ts +0 -1
  31. package/dist/runtime/shared/breadcrumbs.js +0 -18
  32. package/dist/runtime/types.d.ts +0 -6
  33. package/dist/runtime/types.js +0 -0
  34. package/dist/types.d.mts +0 -3
package/dist/module.mjs DELETED
@@ -1,547 +0,0 @@
1
- import { useNuxt, addTypeTemplate, defineNuxtModule, useLogger, createResolver, addServerHandler, hasNuxtModule, addPlugin, addImports, addVitePlugin } from '@nuxt/kit';
2
- import UnheadVite from '@unhead/addons/vite';
3
- import { defu } from 'defu';
4
- import { installNuxtSiteConfig } from 'nuxt-site-config/kit';
5
- import { resolve, relative, extname, dirname, basename } from 'pathe';
6
- import { unpackMeta } from '@unhead/vue/utils';
7
- import fg from 'fast-glob';
8
- import fs from 'node:fs';
9
- import { encodePath, joinURL } from 'ufo';
10
- import escapeRE from 'escape-string-regexp';
11
- import { readFile } from 'node:fs/promises';
12
- import imageSize from 'image-size';
13
-
14
- function extendNuxtConfigAppHeadSeoMeta(nuxt = useNuxt()) {
15
- const seoMeta = nuxt.options.app?.seoMeta || nuxt.options.app?.head?.seoMeta || {};
16
- const configSeoMeta = nuxt.options.seo?.meta || nuxt.options.seo?.seoMeta || {};
17
- if (!seoMeta && !configSeoMeta)
18
- return;
19
- nuxt.options.app.head = nuxt.options.app.head || {};
20
- nuxt.options.app.head = {
21
- ...nuxt.options.app.head,
22
- meta: [
23
- ...nuxt.options.app.head.meta || [],
24
- // @ts-expect-error untyped
25
- ...unpackMeta(seoMeta),
26
- ...unpackMeta(configSeoMeta || {})
27
- ]
28
- };
29
- delete nuxt.options.app.seoMeta;
30
- delete nuxt.options.app.head.seoMeta;
31
- }
32
-
33
- function extendNuxtConfigAppHeadTypes(nuxt = useNuxt()) {
34
- addTypeTemplate({
35
- filename: "module/nuxt-seo-utils.assets.d.ts",
36
- getContents: async () => {
37
- const paths = (await fg(["**/*"], { cwd: resolve(nuxt.options.srcDir, "public") })).map((p) => `/${p}`);
38
- const jsPaths = paths.filter((p) => p.endsWith(".js") || p.endsWith(".mjs"));
39
- return `// Generated by nuxt-seo-utils
40
- declare module '#app' {
41
- import { HeadEntry, HeadTag } from '@unhead/vue/types'
42
-
43
- interface RuntimeNuxtHooks {
44
- 'head:tags': (tag: HeadTag[]) => Promise<void> | void
45
- 'head:entries': (entries: HeadEntry[]) => Promise<void> | void
46
- }
47
- }
48
- declare module '@unhead/schema' {
49
-
50
- type PublicFiles = ${[...paths.map((p) => `'${p}'`), "(string & Record<never, never>)"].join(" | ")}
51
- type JsFiles = ${[...jsPaths.map((p) => `'${p}'`), "(string & Record<never, never>)"].join(" | ")}
52
-
53
- interface SchemaAugmentations {
54
- link: import('@unhead/schema').UserTagConfigWithoutInnerContent & {
55
- href: PublicFiles
56
- }
57
- script: import('@unhead/schema').TagUserProperties & {
58
- src: JsFiles
59
- }
60
- }
61
- }
62
-
63
- export {}
64
- `;
65
- }
66
- }, {
67
- nuxt: true
68
- });
69
- }
70
-
71
- const MetaTagFileGlobs = [
72
- "**/*og-image.{png,jpg,jpeg,gif}",
73
- "**/*opengraph-image.{png,jpg,jpeg,gif}",
74
- "**/*twitter-image.{png,jpg,jpeg,gif}",
75
- "**/*apple-icon.{jpg,jpeg,png}",
76
- "**/*apple-touch.{jpg,jpeg,png}",
77
- "**/*apple-touch-*.{jpg,jpeg,png}",
78
- "**/*apple-touch-icon.{jpg,jpeg,png}",
79
- "**/*apple-touch-icon-*.{jpg,jpeg,png}",
80
- "**/*icon.{ico,jpg,jpeg,png,svg}",
81
- "**/*icon-*.{ico,jpg,jpeg,png,svg}"
82
- ];
83
-
84
- function generateNuxtPageFromFile(file, pagesDir) {
85
- const segments = relative(pagesDir, file).replace(new RegExp(`${escapeRE(extname(file))}$`), "").split("/");
86
- const route = {
87
- name: "",
88
- path: "",
89
- file,
90
- children: []
91
- };
92
- let parent = [];
93
- for (let i = 0; i < segments.length; i++) {
94
- const segment = segments[i] || "";
95
- const tokens = parseSegment(segment);
96
- const segmentName = tokens.map(({ value }) => value).join("");
97
- route.name += (route.name && "-") + segmentName;
98
- const child = parent.find((parentRoute) => parentRoute.name === route.name && !parentRoute.path.endsWith("(.*)*"));
99
- if (child && child.children) {
100
- parent = child.children;
101
- route.path = "";
102
- } else if (segmentName === "index" && !route.path) {
103
- route.path += "/";
104
- } else if (segmentName !== "index") {
105
- route.path += getRoutePath(tokens);
106
- }
107
- }
108
- if (route.name)
109
- route.name = route.name.replace(/-index$/, "");
110
- return route;
111
- }
112
- function getRoutePath(tokens) {
113
- return tokens.reduce((path, token) => {
114
- return path + (token.type === 2 /* optional */ ? `:${token.value}?` : token.type === 1 /* dynamic */ ? `:${token.value}` : token.type === 3 /* catchall */ ? `:${token.value}(.*)*` : encodePath(token.value));
115
- }, "/");
116
- }
117
- const PARAM_CHAR_RE = /[\w.]/;
118
- function parseSegment(segment) {
119
- let state = 0 /* initial */;
120
- let i = 0;
121
- let buffer = "";
122
- const tokens = [];
123
- function consumeBuffer() {
124
- if (!buffer)
125
- return;
126
- if (state === 0 /* initial */)
127
- throw new Error("wrong state");
128
- tokens.push({
129
- type: state === 1 /* static */ ? 0 /* static */ : state === 2 /* dynamic */ ? 1 /* dynamic */ : state === 3 /* optional */ ? 2 /* optional */ : 3 /* catchall */,
130
- value: buffer
131
- });
132
- buffer = "";
133
- }
134
- while (i < segment.length) {
135
- const c = segment[i] || "";
136
- switch (state) {
137
- case 0 /* initial */:
138
- buffer = "";
139
- if (c === "[") {
140
- state = 2 /* dynamic */;
141
- } else {
142
- i--;
143
- state = 1 /* static */;
144
- }
145
- break;
146
- case 1 /* static */:
147
- if (c === "[") {
148
- consumeBuffer();
149
- state = 2 /* dynamic */;
150
- } else {
151
- buffer += c;
152
- }
153
- break;
154
- case 4 /* catchall */:
155
- case 2 /* dynamic */:
156
- case 3 /* optional */:
157
- if (buffer === "...") {
158
- buffer = "";
159
- state = 4 /* catchall */;
160
- }
161
- if (c === "[" && state === 2 /* dynamic */)
162
- state = 3 /* optional */;
163
- if (c === "]" && (state !== 3 /* optional */ || buffer[buffer.length - 1] === "]")) {
164
- if (!buffer)
165
- throw new Error("Empty param");
166
- else
167
- consumeBuffer();
168
- state = 0 /* initial */;
169
- } else if (PARAM_CHAR_RE.test(c)) {
170
- buffer += c;
171
- } else ;
172
- break;
173
- }
174
- i++;
175
- }
176
- if (state === 2 /* dynamic */)
177
- throw new Error(`Unfinished param "${buffer}"`);
178
- consumeBuffer();
179
- return tokens;
180
- }
181
-
182
- function hasLinkRel(input, rel) {
183
- return input.link?.some((link) => link.rel === rel);
184
- }
185
- function hasMetaProperty(input, property) {
186
- return input.meta?.some((meta) => meta.property === property);
187
- }
188
- async function getImageMeta(base, path, isIcon = false) {
189
- const absolutePath = resolve(base, path);
190
- const file = absolutePath.split("/").pop();
191
- const keyword = file.split(".")[0];
192
- let ext = absolutePath.split(".").pop();
193
- if (ext === "jpg")
194
- ext = "jpeg";
195
- const { width, height } = await getImageDimensions(absolutePath);
196
- const payload = {
197
- type: ext === "svg" ? `image/svg+xml` : `image/${ext}`
198
- };
199
- if (!isIcon) {
200
- payload.width = width;
201
- payload.height = height;
202
- const altTextPath = resolve(dirname(absolutePath), `${keyword}.alt.txt`);
203
- if (fs.existsSync(altTextPath)) {
204
- payload.alt = fs.readFileSync(altTextPath, "utf8");
205
- payload.alt = String(payload.alt).replace(/\n/g, " ").trim();
206
- }
207
- } else {
208
- if (path.includes(".dark") || path.includes("-dark"))
209
- payload.media = "(prefers-color-scheme: dark)";
210
- else if (path.includes(".light") || path.includes("-light"))
211
- payload.media = "(prefers-color-scheme: light)";
212
- if (ext !== "svg") {
213
- payload.sizes = `${width}x${height}`;
214
- } else {
215
- payload.sizes = "any";
216
- }
217
- }
218
- return payload;
219
- }
220
- async function getImageDimensions(absolutePath) {
221
- const buffer = await readFile(absolutePath);
222
- return imageSize(buffer);
223
- }
224
-
225
- async function generateTagsFromPageDirImages(nuxt = useNuxt()) {
226
- const pagesDir = resolve(nuxt.options.rootDir, nuxt.options.dir.pages);
227
- const files = await fg(MetaTagFileGlobs, { cwd: pagesDir, onlyFiles: true });
228
- const appendRouteRules = {};
229
- const devMiddlewareMap = {};
230
- const nitroOutputMap = [];
231
- for (const file of files) {
232
- const fileName = basename(file);
233
- const keyword = fileName.split(".")[0] || "";
234
- let { path } = generateNuxtPageFromFile(resolve(pagesDir, dirname(file)), pagesDir);
235
- const meta = await getImageMeta(pagesDir, file);
236
- if (path.endsWith("/_dir"))
237
- path = path.replace(/\/_dir$/, "");
238
- const src = joinURL(path, fileName);
239
- if (["icon", "apple-touch-icon", "apple-icon"].includes(keyword) || keyword.startsWith("icon-")) {
240
- appendRouteRules[`${path}/**`] = {
241
- head: {
242
- link: [
243
- { rel: keyword, type: meta.type, href: src, sizes: meta.sizes }
244
- ]
245
- }
246
- };
247
- } else {
248
- appendRouteRules[`${path}/**`] = {
249
- seoMeta: {
250
- [["opengraph-image", "og-image"].includes(keyword) ? "ogImage" : "twitterImage"]: [{ url: src, ...meta, sizes: void 0 }]
251
- }
252
- };
253
- }
254
- devMiddlewareMap[src] = resolve(pagesDir, file);
255
- nitroOutputMap.push({
256
- src: resolve(pagesDir, file),
257
- dest: src.slice(1)
258
- // remove leading slash
259
- });
260
- }
261
- nuxt.options.routeRules = defu(appendRouteRules, nuxt.options.routeRules);
262
- nuxt.options.nitro.routeRules = defu(appendRouteRules, nuxt.options.nitro.routeRules);
263
- if (nuxt.options.dev) {
264
- nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
265
- nitroConfig.virtual["#seo-utils-virtual/pageDirImages"] = `export const fileMapping = ${JSON.stringify(devMiddlewareMap)}`;
266
- });
267
- }
268
- nuxt.hooks.hook("nitro:build:public-assets", (_nitro) => {
269
- const publicDir = resolve(_nitro.options.output.dir, _nitro.options.output.publicDir);
270
- nitroOutputMap.forEach(({ src, dest }) => {
271
- const resolvedDest = resolve(publicDir, dest);
272
- const destFolder = dirname(resolvedDest);
273
- if (!fs.existsSync(destFolder))
274
- fs.mkdirSync(destFolder, { recursive: true });
275
- if (!fs.existsSync(resolvedDest))
276
- fs.copyFileSync(src, resolvedDest);
277
- });
278
- });
279
- }
280
-
281
- async function generateTagsFromPublicFiles(nuxt = useNuxt()) {
282
- const publicDirPath = resolve(nuxt.options.rootDir, nuxt.options.dir.public);
283
- const rootPublicFiles = (await fg(MetaTagFileGlobs, { cwd: publicDirPath, onlyFiles: true, deep: 1 })).map((file) => basename(file));
284
- const headConfig = defu(nuxt.options.app.head, {
285
- link: [],
286
- meta: []
287
- });
288
- if (!hasLinkRel(headConfig, "icon")) {
289
- if (rootPublicFiles.includes("favicon.ico") && nuxt.options.app.baseURL !== "/") {
290
- headConfig.link.push({
291
- rel: "icon",
292
- href: joinURL(nuxt.options.app.baseURL, "favicon.ico"),
293
- sizes: "any"
294
- });
295
- }
296
- const isIcon = (file) => file.includes("icon") && !file.endsWith(".ico");
297
- const isAppleTouchIcon = (file) => file.includes("apple-icon") || file.includes("apple-touch-icon") || file.includes("apple-touch");
298
- headConfig.link.push(
299
- ...await Promise.all([
300
- ...rootPublicFiles.filter((file) => isIcon(file) && !isAppleTouchIcon(file)).sort().map(async (iconFile) => {
301
- const meta = await getImageMeta(publicDirPath, iconFile, true);
302
- return {
303
- rel: "icon",
304
- href: joinURL(nuxt.options.app.baseURL, iconFile),
305
- ...meta
306
- };
307
- }),
308
- ...rootPublicFiles.filter((file) => isAppleTouchIcon(file)).sort().map(async (appleIconFile) => {
309
- const meta = await getImageMeta(publicDirPath, appleIconFile, true);
310
- return {
311
- rel: "apple-touch-icon",
312
- href: joinURL(nuxt.options.app.baseURL, appleIconFile),
313
- ...meta
314
- };
315
- })
316
- ])
317
- );
318
- }
319
- let hasTwitterImage = hasMetaProperty(headConfig, "twitter:image");
320
- if (!hasTwitterImage) {
321
- const twitterImageFiles = rootPublicFiles.filter((file) => file.startsWith("twitter-image.")).sort();
322
- if (twitterImageFiles.length) {
323
- headConfig.meta.push(
324
- ...(await Promise.all(twitterImageFiles.map(async (twitterImageFile) => {
325
- const dimensions = await getImageDimensions(resolve(publicDirPath, twitterImageFile));
326
- return unpackMeta({
327
- twitterImage: {
328
- url: twitterImageFile,
329
- width: dimensions.width,
330
- height: dimensions.height
331
- }
332
- });
333
- }))).flat()
334
- );
335
- hasTwitterImage = true;
336
- }
337
- }
338
- if (!hasMetaProperty(headConfig, "og:image")) {
339
- const ogImageFiles = rootPublicFiles.filter((file) => file.startsWith("og-image.") || file.startsWith("og.")).sort();
340
- if (ogImageFiles.length) {
341
- headConfig.meta.push(
342
- ...(await Promise.all(ogImageFiles.map(async (src) => {
343
- const meta = await getImageMeta(publicDirPath, src, false);
344
- delete meta.sizes;
345
- const seoMeta = {
346
- ogImage: {
347
- url: src,
348
- ...meta
349
- }
350
- };
351
- if (!hasTwitterImage) {
352
- seoMeta.twitterImage = {
353
- url: src,
354
- ...meta
355
- };
356
- }
357
- return unpackMeta(seoMeta);
358
- }))).flat()
359
- );
360
- }
361
- }
362
- nuxt.options.app.head = headConfig;
363
- }
364
-
365
- function setupNuxtConfigAppHeadWithMoreDefaults(nuxt = useNuxt()) {
366
- const headConfig = nuxt.options.app.head;
367
- headConfig.link = headConfig.link || [];
368
- headConfig.htmlAttrs = headConfig.htmlAttrs || {};
369
- headConfig.link = headConfig.link || [];
370
- headConfig.meta = headConfig.meta || [];
371
- if (!hasMetaProperty(headConfig, "og:type")) {
372
- headConfig.meta.push({
373
- property: "og:type",
374
- content: "website"
375
- });
376
- }
377
- nuxt.options.app.head = headConfig;
378
- }
379
-
380
- const module = defineNuxtModule({
381
- meta: {
382
- name: "nuxt-seo-utils",
383
- configKey: "seo",
384
- compatibility: {
385
- nuxt: ">=3.16.0"
386
- }
387
- },
388
- defaults: {
389
- enabled: true,
390
- debug: false,
391
- redirectToCanonicalSiteUrl: false,
392
- automaticDefaults: true,
393
- fallbackTitle: true,
394
- metaDataFiles: true,
395
- mergeWithSiteConfig: true,
396
- extendRouteRules: true,
397
- fixRequiredAbsoluteMetaTagsLinks: true,
398
- extendNuxtConfigAppHeadSeoMeta: true,
399
- treeShakeUseSeoMeta: true,
400
- extendNuxtConfigAppHeadTypes: true,
401
- setupNuxtConfigAppHeadWithMoreDefaults: true,
402
- automaticOgAndTwitterTags: true,
403
- canonicalLowercase: true
404
- },
405
- async setup(config, nuxt) {
406
- const logger = useLogger("nuxt-seo-utils");
407
- logger.level = config.debug || nuxt.options.debug ? 4 : 3;
408
- if (config.enabled === false) {
409
- logger.debug("The module is disabled, skipping setup.");
410
- return;
411
- }
412
- const { resolve } = createResolver(import.meta.url);
413
- await installNuxtSiteConfig();
414
- const runtimeDir = resolve("./runtime");
415
- if (config.metaDataFiles) {
416
- await generateTagsFromPublicFiles();
417
- await generateTagsFromPageDirImages();
418
- if (nuxt.options.dev) {
419
- addServerHandler({
420
- middleware: true,
421
- handler: resolve(runtimeDir, "server/middleware/resolveImagesInPagesDir")
422
- });
423
- }
424
- }
425
- const hasI18n = hasNuxtModule("@nuxtjs/i18n") || hasNuxtModule("nuxt-i18n-micro");
426
- if (config.automaticDefaults) {
427
- if (hasI18n) {
428
- addPlugin({
429
- src: resolve(runtimeDir, `./app/plugins/defaultsWaitI18n`)
430
- });
431
- } else {
432
- addPlugin({
433
- src: resolve(runtimeDir, `./app/plugins/defaults`)
434
- });
435
- }
436
- }
437
- if (config.fallbackTitle) {
438
- addPlugin({
439
- src: resolve(runtimeDir, "./app/plugins/titles")
440
- });
441
- }
442
- if (!hasI18n) {
443
- addImports({
444
- from: resolve(runtimeDir, `./app/composables/polyfills`),
445
- name: "useI18n"
446
- });
447
- }
448
- addImports({
449
- from: resolve(runtimeDir, `./app/composables/useBreadcrumbItems`),
450
- name: "useBreadcrumbItems"
451
- });
452
- const polyfills = [
453
- // @ts-expect-error runtime type
454
- ...!hasNuxtModule("nuxt-schema-org") || nuxt.options.schemaOrg?.enable === false ? [
455
- "useSchemaOrg",
456
- "defineWebSite",
457
- "defineWebPage",
458
- "defineBreadcrumb"
459
- ] : []
460
- ];
461
- polyfills.forEach((name) => {
462
- addImports({
463
- from: resolve(runtimeDir, "./app/composables/polyfills"),
464
- name
465
- });
466
- });
467
- nuxt.options.experimental.headNext = true;
468
- if (!nuxt.options.dev && config.redirectToCanonicalSiteUrl) {
469
- addServerHandler({
470
- handler: resolve(runtimeDir, "./server/middleware/redirectCanonical"),
471
- middleware: true
472
- });
473
- }
474
- nuxt.options.alias["#seo-utils"] = runtimeDir;
475
- nuxt.options.runtimeConfig.public["seo-utils"] = defu(nuxt.options.runtimeConfig.public["seo-utils"] || {}, {
476
- canonicalQueryWhitelist: config.canonicalQueryWhitelist || [
477
- "page",
478
- "sort",
479
- "filter",
480
- "search",
481
- "q",
482
- "category",
483
- "tag"
484
- ],
485
- canonicalLowercase: config.canonicalLowercase
486
- });
487
- if (config.extendNuxtConfigAppHeadSeoMeta)
488
- extendNuxtConfigAppHeadSeoMeta();
489
- if (config.setupNuxtConfigAppHeadWithMoreDefaults)
490
- setupNuxtConfigAppHeadWithMoreDefaults(nuxt);
491
- if (config.extendNuxtConfigAppHeadTypes)
492
- extendNuxtConfigAppHeadTypes();
493
- addTypeTemplate({
494
- filename: "module/nuxt-seo-utils.d.ts",
495
- getContents: (data) => {
496
- const typesPath = relative(resolve(data.nuxt.options.rootDir, data.nuxt.options.buildDir, "module"), resolve("runtime/types"));
497
- const types = ` interface NitroRouteRules {
498
- seoMeta?: import('${typesPath}').MetaFlatSerializable
499
- head?: import('${typesPath}').Head
500
- }
501
- interface NitroRouteConfig {
502
- seoMeta?: import('${typesPath}').MetaFlatSerializable
503
- head?: import('${typesPath}').Head
504
- }`;
505
- return `// Generated by nuxt-seo-utils
506
-
507
- import type { RobotsContext } from '#robots/types'
508
-
509
- declare module 'nitropack/types' {
510
- ${types}
511
- }
512
-
513
- declare module 'nitropack' {
514
- ${types}
515
- }
516
-
517
-
518
- declare module '@nuxt/schema' {
519
- interface AppHeadMetaObject { seoMeta?: import('${typesPath}').MetaFlatSerializable }
520
- }
521
-
522
- declare module 'nuxt/schema' {
523
- interface AppHeadMetaObject { seoMeta?: import('${typesPath}').MetaFlatSerializable }
524
- }
525
-
526
- export {}
527
- `;
528
- }
529
- }, {
530
- nitro: true,
531
- nuxt: true
532
- });
533
- const appRuntimeDir = resolve(runtimeDir, "./app");
534
- if (config.treeShakeUseSeoMeta)
535
- addVitePlugin(UnheadVite());
536
- if (config.automaticOgAndTwitterTags)
537
- addPlugin({ src: resolve(appRuntimeDir, "plugins", "inferSeoMetaPlugin") });
538
- if (config.mergeWithSiteConfig)
539
- addPlugin({ src: resolve(appRuntimeDir, "plugins", "siteConfig") });
540
- if (config.extendRouteRules)
541
- addPlugin({ src: resolve(appRuntimeDir, "plugins", "0.routeRules") });
542
- if (config.fixRequiredAbsoluteMetaTagsLinks)
543
- addPlugin({ src: resolve(appRuntimeDir, "plugins", "1.absoluteImageUrls.server"), mode: "server" });
544
- }
545
- });
546
-
547
- export { module as default };
@@ -1,11 +0,0 @@
1
- export declare function useSchemaOrg(): void;
2
- export declare function defineWebSite(): void;
3
- export declare function defineWebPage(): void;
4
- export declare function defineBreadcrumb(): void;
5
- export declare function useI18n(): {
6
- t: (_: string, fallback: string, options: any) => string;
7
- te: (_: string) => boolean;
8
- strategy: string;
9
- defaultLocale: import("vue").ComputedRef<any>;
10
- locale: import("vue").ComputedRef<any>;
11
- };
@@ -1,27 +0,0 @@
1
- import { useSiteConfig } from "#site-config/app/composables/useSiteConfig";
2
- import { computed, toValue } from "vue";
3
- export function useSchemaOrg() {
4
- }
5
- export function defineWebSite() {
6
- }
7
- export function defineWebPage() {
8
- }
9
- export function defineBreadcrumb() {
10
- }
11
- export function useI18n() {
12
- const siteConfig = useSiteConfig({
13
- resolveRefs: false
14
- });
15
- return {
16
- // eslint-disable-next-line unused-imports/no-unused-vars
17
- t: (_, fallback, options) => fallback,
18
- te: (_) => false,
19
- strategy: "no_prefix",
20
- defaultLocale: computed(() => {
21
- return toValue(siteConfig.defaultLocale) || "en";
22
- }),
23
- locale: computed(() => {
24
- return toValue(siteConfig.currentLocale) || toValue(siteConfig.defaultLocale) || "en";
25
- })
26
- };
27
- }
@@ -1,112 +0,0 @@
1
- import type { NuxtLinkProps } from 'nuxt/app';
2
- import type { MaybeRefOrGetter } from 'vue';
3
- interface NuxtUIBreadcrumbItem extends NuxtLinkProps {
4
- label: string;
5
- labelClass?: string;
6
- icon?: string;
7
- iconClass?: string;
8
- as?: string;
9
- type?: 'button' | 'submit' | 'reset';
10
- disabled?: boolean;
11
- active?: boolean;
12
- exact?: boolean;
13
- exactQuery?: boolean;
14
- exactMatch?: boolean;
15
- inactiveClass?: string;
16
- [key: string]: any;
17
- }
18
- export interface BreadcrumbProps {
19
- /**
20
- * Generate the breadcrumbs based on a different path than the current route.
21
- */
22
- path?: MaybeRefOrGetter<string>;
23
- /**
24
- * The id of the breadcrumb list. It's recommended to provide a unique
25
- * id when adding multiple breadcrumb lists to the same page.
26
- */
27
- id?: string;
28
- /**
29
- * Append additional breadcrumb items to the end of the list. This is applied
30
- * after the `overrides` option.
31
- */
32
- append?: MaybeRefOrGetter<BreadcrumbItemProps[]>;
33
- /**
34
- * Prepend additional breadcrumb items to the start of the list. This is applied
35
- * after the `overrides` option.
36
- */
37
- prepend?: MaybeRefOrGetter<BreadcrumbItemProps[]>;
38
- /**
39
- * Override any of the breadcrumb items based on the index.
40
- */
41
- overrides?: MaybeRefOrGetter<(BreadcrumbItemProps | false | undefined)[]>;
42
- /**
43
- * Should the schema.org breadcrumb be generated.
44
- * @default true
45
- */
46
- schemaOrg?: boolean;
47
- /**
48
- * The Aria Label for the breadcrumbs.
49
- * You shouldn't need to change this.
50
- *
51
- * @default 'Breadcrumbs'
52
- */
53
- ariaLabel?: string;
54
- /**
55
- * Should the current breadcrumb item be shown.
56
- *
57
- * @default false
58
- */
59
- hideCurrent?: MaybeRefOrGetter<boolean>;
60
- /**
61
- * Should the root breadcrumb be shown.
62
- */
63
- hideRoot?: MaybeRefOrGetter<boolean>;
64
- /**
65
- * Should breadcrumb items with non-existing path be shown.
66
- *
67
- * By default, every path segments will be present in breadcrumb list even if there is no corresponding page for such segment.
68
- *
69
- * @default false
70
- */
71
- hideNonExisting?: MaybeRefOrGetter<boolean>;
72
- /**
73
- * The root segment of the breadcrumb list.
74
- *
75
- * By default, this will be `/`, unless you're using Nuxt I18n with a prefix strategy.
76
- */
77
- rootSegment?: string;
78
- }
79
- export type ResolvedBreadcrumbProps = {
80
- [key in keyof BreadcrumbProps]: BreadcrumbProps[key] extends MaybeRefOrGetter<infer T> ? T : BreadcrumbProps[key];
81
- };
82
- export interface BreadcrumbItemProps extends NuxtUIBreadcrumbItem {
83
- /** Whether the breadcrumb item represents the aria-current. */
84
- current?: boolean;
85
- /**
86
- * The type of current location the breadcrumb item represents, if `isCurrent` is true.
87
- * @default 'page'
88
- */
89
- ariaCurrent?: 'page' | 'step' | 'location' | 'date' | 'time' | boolean | 'true' | 'false';
90
- to?: string;
91
- ariaLabel?: string;
92
- separator?: boolean | string;
93
- class?: (string | string[] | undefined)[] | string;
94
- /**
95
- * @internal
96
- */
97
- _props?: {
98
- first: boolean;
99
- last: boolean;
100
- };
101
- }
102
- /**
103
- * Generate an automatic breadcrumb list that helps users to navigate between pages.
104
- *
105
- * - Integrates with [Nuxt Schema.org](/schema-org/getting-started/installation) to generate [BreadcrumbList](https://schema.org/BreadcrumbList) structured data.
106
- * - Integrates with [Nuxt I18n](https://i18n.nuxtjs.org/) to generate localized breadcrumbs.
107
- *
108
- * @see https://github.com/harlan-zw/nuxt-seo/blob/main/src/runtime/nuxt/composables/useBreadcrumbItems.ts
109
- * @docs https://nuxtseo.com/nuxt-seo/api/breadcrumbs
110
- */
111
- export declare function useBreadcrumbItems(_options?: BreadcrumbProps): import("vue").ComputedRef<BreadcrumbItemProps[]>;
112
- export {};