@nuxtjs/sitemap 8.3.4 → 8.4.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.
- package/dist/devtools/nuxt.config.ts +4 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +92 -29
- package/dist/runtime/server/routes/__sitemap__/content-urls.d.ts +9 -0
- package/dist/runtime/server/routes/__sitemap__/content-urls.js +34 -0
- package/dist/runtime/types.d.ts +1 -1
- package/package.json +13 -12
- package/dist/runtime/server/routes/__sitemap__/nuxt-content-urls-v3.d.ts +0 -2
- package/dist/runtime/server/routes/__sitemap__/nuxt-content-urls-v3.js +0 -40
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
1
2
|
import { resolve } from 'pathe'
|
|
2
3
|
|
|
4
|
+
const currentDir = fileURLToPath(new URL('.', import.meta.url))
|
|
5
|
+
|
|
3
6
|
// Nuxt SEO devtools panel, shipped as a layer (Model C). Components flat-registered
|
|
4
7
|
// so intra-panel references resolve by name.
|
|
5
8
|
export default defineNuxtConfig({
|
|
6
|
-
components: [{ path: resolve(
|
|
9
|
+
components: [{ path: resolve(currentDir, './components'), pathPrefix: false }],
|
|
7
10
|
})
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -2,14 +2,14 @@ import { useNuxt, hasNuxtModule, addTypeTemplate, addTemplate, defineNuxtModule,
|
|
|
2
2
|
import { defu } from 'defu';
|
|
3
3
|
import { withSiteUrl, installNuxtSiteConfig } from 'nuxt-site-config/kit';
|
|
4
4
|
import { isPathFile } from 'nuxt-site-config/urls';
|
|
5
|
-
import { isNuxtGenerate, renderNitroTypeAugmentations, useModuleLogger, setupNitroRuntimeCompatibility, getNuxtModuleOptions, resolveNitroPreset,
|
|
5
|
+
import { isNuxtGenerate, renderNitroTypeAugmentations, useModuleLogger, setupNitroRuntimeCompatibility, getNuxtModuleOptions, resolveNitroPreset, resolveContentProvider, setupContentRuntime, createPagesPromise, createNitroPromise } from 'nuxtseo-shared/kit';
|
|
6
6
|
import { serializeFilters } from 'nuxtseo-shared/utils';
|
|
7
7
|
import { dirname, extname } from 'pathe';
|
|
8
8
|
import { readPackageJSON } from 'pkg-types';
|
|
9
9
|
import { withBase, withHttps, withTrailingSlash, withoutLeadingSlash, joinURL, withLeadingSlash } from 'ufo';
|
|
10
10
|
import { setupDevToolsUI as setupDevToolsUI$1 } from 'nuxtseo-shared/devtools';
|
|
11
11
|
import { readFileSync, statSync } from 'node:fs';
|
|
12
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { rm, mkdir, writeFile } from 'node:fs/promises';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { colors } from 'consola/utils';
|
|
15
15
|
import { splitForLocales, createPathFilter } from '../dist/runtime/utils-pure.js';
|
|
@@ -18,6 +18,9 @@ import { normaliseDate } from '../dist/runtime/server/sitemap/urlset/normalise.j
|
|
|
18
18
|
import { mapPathForI18nPages, splitPathForI18nLocales as splitPathForI18nLocales$1, expandCompactLocaleRoute, normalizeLocales, generatePathForI18nPages } from 'nuxtseo-shared/i18n';
|
|
19
19
|
import 'ultrahtml';
|
|
20
20
|
|
|
21
|
+
const COMARK_CONTENT_SOURCE = "@harlan-zw/comark-content:urls";
|
|
22
|
+
const COMARK_CONTENT_SITEMAP_ROUTE = "/__sitemap__/comark-content-urls.json";
|
|
23
|
+
|
|
21
24
|
function setupDevToolsUI(_options, resolve, nuxt = useNuxt()) {
|
|
22
25
|
setupDevToolsUI$1(
|
|
23
26
|
{ route: "/__nuxt-sitemap", name: "sitemap", title: "Sitemap", icon: "carbon:load-balancer-application" },
|
|
@@ -72,6 +75,10 @@ export async function readSourcesFromFilesystem(filename) {
|
|
|
72
75
|
`;
|
|
73
76
|
});
|
|
74
77
|
nuxt.hooks.hook("nitro:init", async (nitro) => {
|
|
78
|
+
await Promise.all([
|
|
79
|
+
rm(join(runtimeAssetsPath, "global-sources.json"), { force: true }),
|
|
80
|
+
rm(join(runtimeAssetsPath, "child-sources.json"), { force: true })
|
|
81
|
+
]);
|
|
75
82
|
nitro.hooks.hook("prerender:generate", async (route) => {
|
|
76
83
|
const html = route.contents;
|
|
77
84
|
if (!route.fileName?.endsWith(".html") || !html || ["/200.html", "/404.html"].includes(route.route))
|
|
@@ -455,7 +462,34 @@ function generateExtraRoutesFromNuxtConfig(nuxt = useNuxt()) {
|
|
|
455
462
|
}).map(([k]) => k).filter(filterForValidPage);
|
|
456
463
|
return { routeRules };
|
|
457
464
|
}
|
|
465
|
+
function resolveExcludedAppSources(resolved, authored) {
|
|
466
|
+
if (resolved === true || authored === true)
|
|
467
|
+
return true;
|
|
468
|
+
if (!Array.isArray(authored))
|
|
469
|
+
return resolved;
|
|
470
|
+
const excluded = [...resolved];
|
|
471
|
+
for (const source of authored) {
|
|
472
|
+
if (typeof source === "string" && !excluded.includes(source))
|
|
473
|
+
excluded.push(source);
|
|
474
|
+
}
|
|
475
|
+
return excluded;
|
|
476
|
+
}
|
|
458
477
|
|
|
478
|
+
const IMAGE_TAGS = /* @__PURE__ */ new Set(["image", "img", "nuxtimg", "nuxt-img"]);
|
|
479
|
+
function discoverContentImages(body) {
|
|
480
|
+
const images = [];
|
|
481
|
+
const walk = (nodes) => {
|
|
482
|
+
for (const node of nodes || []) {
|
|
483
|
+
if (!Array.isArray(node) || typeof node[0] !== "string")
|
|
484
|
+
continue;
|
|
485
|
+
if (IMAGE_TAGS.has(node[0]) && node[1]?.src)
|
|
486
|
+
images.push({ loc: node[1].src });
|
|
487
|
+
walk(node.slice(2));
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
walk(body?.value ?? body?.nodes);
|
|
491
|
+
return images;
|
|
492
|
+
}
|
|
459
493
|
const module$1 = defineNuxtModule({
|
|
460
494
|
meta: {
|
|
461
495
|
name: "@nuxtjs/sitemap",
|
|
@@ -480,6 +514,10 @@ const module$1 = defineNuxtModule({
|
|
|
480
514
|
version: ">=2",
|
|
481
515
|
optional: true
|
|
482
516
|
},
|
|
517
|
+
"@harlan-zw/comark-content": {
|
|
518
|
+
version: ">=0.1.2",
|
|
519
|
+
optional: true
|
|
520
|
+
},
|
|
483
521
|
"@nuxtjs/robots": {
|
|
484
522
|
version: ">=4",
|
|
485
523
|
optional: true
|
|
@@ -673,11 +711,11 @@ const module$1 = defineNuxtModule({
|
|
|
673
711
|
const hasCustomI18nSitemaps = i18nSitemaps.length > 0;
|
|
674
712
|
if (hasCustomI18nSitemaps) {
|
|
675
713
|
for (const { name: name2, cfg } of i18nSitemaps) {
|
|
714
|
+
const { sitemapName: _sitemapName, _route, _isChunking, _chunkSize, _chunkCount, ...inheritedConfig } = cfg;
|
|
676
715
|
for (const locale of resolvedAutoI18n.locales) {
|
|
677
716
|
newSitemaps[`${locale._sitemap}-${name2}`] = {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
...cfg.include?.length && { include: cfg.include }
|
|
717
|
+
...inheritedConfig,
|
|
718
|
+
includeAppSources: true
|
|
681
719
|
};
|
|
682
720
|
}
|
|
683
721
|
}
|
|
@@ -770,20 +808,13 @@ const module$1 = defineNuxtModule({
|
|
|
770
808
|
addServerPlugin(resolve("./runtime/server/plugins/stream-transport"));
|
|
771
809
|
}
|
|
772
810
|
const isNuxtContentDocumentDriven = !!nuxt.options.content?.documentDriven || config.strictNuxtContentPaths;
|
|
773
|
-
const
|
|
774
|
-
const isNuxtContentV3 =
|
|
811
|
+
const contentProvider = await resolveContentProvider(nuxt);
|
|
812
|
+
const isNuxtContentV3 = contentProvider._tag === "NuxtContent" && contentProvider.version === 3;
|
|
813
|
+
const isNuxtContentV2 = contentProvider._tag === "NuxtContent" && contentProvider.version === 2;
|
|
814
|
+
const isComarkContent = contentProvider._tag === "Comark";
|
|
775
815
|
const nuxtV3Collections = /* @__PURE__ */ new Set();
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
if (nuxt.options._installedModules.some((m) => m.meta.name === "Content")) {
|
|
779
|
-
logger.warn("You have loaded `@nuxt/content` before `@nuxtjs/sitemap`, this may cause issues with the integration. Please ensure `@nuxtjs/sitemap` is loaded first.");
|
|
780
|
-
}
|
|
781
|
-
config.exclude.push("/__nuxt_content/**");
|
|
782
|
-
const needsCustomAlias = await hasNuxtModuleCompatibility("@nuxt/content", "<3.6.0");
|
|
783
|
-
if (needsCustomAlias) {
|
|
784
|
-
nuxt.options.alias["#sitemap/content-v3-nitro-path"] = resolve(dirname(resolveModule("@nuxt/content")), "runtime/nitro");
|
|
785
|
-
nuxt.options.alias["@nuxt/content/nitro"] = resolve("./runtime/server/content-compat");
|
|
786
|
-
}
|
|
816
|
+
setupContentRuntime(contentProvider, nuxt);
|
|
817
|
+
const registerContentSitemapHook = (options) => {
|
|
787
818
|
nuxt.hooks.hook("content:file:afterParse", (ctx) => {
|
|
788
819
|
try {
|
|
789
820
|
const content = ctx.content;
|
|
@@ -792,7 +823,7 @@ const module$1 = defineNuxtModule({
|
|
|
792
823
|
ctx.content.sitemap = null;
|
|
793
824
|
return;
|
|
794
825
|
}
|
|
795
|
-
if (!ctx.collection.fields || !("sitemap" in ctx.collection.fields)) {
|
|
826
|
+
if (options.requireCollectionField && (!ctx.collection.fields || !("sitemap" in ctx.collection.fields))) {
|
|
796
827
|
ctx.content.sitemap = null;
|
|
797
828
|
return;
|
|
798
829
|
}
|
|
@@ -805,13 +836,8 @@ const module$1 = defineNuxtModule({
|
|
|
805
836
|
return;
|
|
806
837
|
}
|
|
807
838
|
const images = [];
|
|
808
|
-
if (config.discoverImages)
|
|
809
|
-
images.push(
|
|
810
|
-
...content.body?.value?.filter(
|
|
811
|
-
(c) => ["image", "img", "nuxtimg", "nuxt-img"].includes(c[0])
|
|
812
|
-
).filter((c) => c[1]?.src).map((c) => ({ loc: c[1].src })) || []
|
|
813
|
-
);
|
|
814
|
-
}
|
|
839
|
+
if (config.discoverImages)
|
|
840
|
+
images.push(...discoverContentImages(content.body));
|
|
815
841
|
const lastmod = content.seo?.articleModifiedTime || content.updatedAt;
|
|
816
842
|
const defaults = {
|
|
817
843
|
loc: content.path
|
|
@@ -825,6 +851,8 @@ const module$1 = defineNuxtModule({
|
|
|
825
851
|
logger.warn(`Failed to process sitemap data for content file (collection: ${ctx.collection?.name}, path: ${ctx.content?.path}), skipping.`, e);
|
|
826
852
|
}
|
|
827
853
|
});
|
|
854
|
+
};
|
|
855
|
+
const addContentCallbackVirtuals = () => {
|
|
828
856
|
nuxt.hook("nitro:config", (nitroConfig) => {
|
|
829
857
|
const filterEntries = [];
|
|
830
858
|
if (globalThis.__sitemapCollectionFilters) {
|
|
@@ -842,9 +870,22 @@ ${filterEntries.join("\n")}`;
|
|
|
842
870
|
nitroConfig.virtual["#sitemap/content-on-url"] = `export const onUrlFns = new Map()
|
|
843
871
|
${onUrlEntries.join("\n")}`;
|
|
844
872
|
});
|
|
873
|
+
};
|
|
874
|
+
if (isNuxtContentV3) {
|
|
875
|
+
if (nuxt.options._installedModules.some((m) => m.meta.name === "Content")) {
|
|
876
|
+
logger.warn("You have loaded `@nuxt/content` before `@nuxtjs/sitemap`, this may cause issues with the integration. Please ensure `@nuxtjs/sitemap` is loaded first.");
|
|
877
|
+
}
|
|
878
|
+
config.exclude.push("/__nuxt_content/**");
|
|
879
|
+
const needsCustomAlias = await hasNuxtModuleCompatibility("@nuxt/content", "<3.6.0");
|
|
880
|
+
if (needsCustomAlias) {
|
|
881
|
+
nuxt.options.alias["#sitemap/content-v3-nitro-path"] = resolve(dirname(resolveModule("@nuxt/content")), "runtime/nitro");
|
|
882
|
+
nuxt.options.alias["@nuxt/content/nitro"] = resolve("./runtime/server/content-compat");
|
|
883
|
+
}
|
|
884
|
+
registerContentSitemapHook({ requireCollectionField: true });
|
|
885
|
+
addContentCallbackVirtuals();
|
|
845
886
|
addServerHandler({
|
|
846
887
|
route: "/__sitemap__/nuxt-content-urls.json",
|
|
847
|
-
handler: resolve("./runtime/server/routes/__sitemap__/
|
|
888
|
+
handler: resolve("./runtime/server/routes/__sitemap__/content-urls")
|
|
848
889
|
});
|
|
849
890
|
if (config.strictNuxtContentPaths) {
|
|
850
891
|
logger.warn("You have set `strictNuxtContentPaths: true` but are using @nuxt/content v3. This is not required, please remove it.");
|
|
@@ -857,6 +898,24 @@ ${onUrlEntries.join("\n")}`;
|
|
|
857
898
|
},
|
|
858
899
|
fetch: "/__sitemap__/nuxt-content-urls.json"
|
|
859
900
|
});
|
|
901
|
+
} else if (isComarkContent) {
|
|
902
|
+
registerContentSitemapHook({ requireCollectionField: false });
|
|
903
|
+
addContentCallbackVirtuals();
|
|
904
|
+
addServerHandler({
|
|
905
|
+
route: COMARK_CONTENT_SITEMAP_ROUTE,
|
|
906
|
+
handler: resolve("./runtime/server/routes/__sitemap__/content-urls")
|
|
907
|
+
});
|
|
908
|
+
if (config.strictNuxtContentPaths) {
|
|
909
|
+
logger.warn("You have set `strictNuxtContentPaths: true` but are using comark-content. This is not required, please remove it.");
|
|
910
|
+
}
|
|
911
|
+
appGlobalSources.push({
|
|
912
|
+
context: {
|
|
913
|
+
name: COMARK_CONTENT_SOURCE,
|
|
914
|
+
description: "Generated from your markdown files.",
|
|
915
|
+
tips: nuxtV3Collections.size ? [`Parsing the following collections: ${Array.from(nuxtV3Collections).join(", ")}`] : ["No collections found. Set `sitemap: false` on a collection to keep it out."]
|
|
916
|
+
},
|
|
917
|
+
fetch: COMARK_CONTENT_SITEMAP_ROUTE
|
|
918
|
+
});
|
|
860
919
|
} else if (isNuxtContentV2) {
|
|
861
920
|
addServerPlugin(resolve("./runtime/server/plugins/nuxt-content-v2"));
|
|
862
921
|
addServerHandler({
|
|
@@ -1097,6 +1156,10 @@ ${onUrlEntries.join("\n")}`;
|
|
|
1097
1156
|
return r.contentType?.includes("text/html");
|
|
1098
1157
|
};
|
|
1099
1158
|
const generateGlobalSources = async () => {
|
|
1159
|
+
const excludedAppSources = resolveExcludedAppSources(
|
|
1160
|
+
config.excludeAppSources,
|
|
1161
|
+
nuxt.options.sitemap?.excludeAppSources
|
|
1162
|
+
);
|
|
1100
1163
|
const { routeRules: routeRules2 } = generateExtraRoutesFromNuxtConfig();
|
|
1101
1164
|
const nitro = await nitroPromise;
|
|
1102
1165
|
const prerenderedRoutes2 = nitro._prerenderedRoutes || [];
|
|
@@ -1173,7 +1236,7 @@ ${onUrlEntries.join("\n")}`;
|
|
|
1173
1236
|
s.sourceType = "user";
|
|
1174
1237
|
return s;
|
|
1175
1238
|
}),
|
|
1176
|
-
...(
|
|
1239
|
+
...(excludedAppSources === true ? [] : [
|
|
1177
1240
|
...appGlobalSources,
|
|
1178
1241
|
{
|
|
1179
1242
|
context: {
|
|
@@ -1205,7 +1268,7 @@ ${onUrlEntries.join("\n")}`;
|
|
|
1205
1268
|
},
|
|
1206
1269
|
urls: prerenderUrlsFinal
|
|
1207
1270
|
}
|
|
1208
|
-
]).filter((s) => !
|
|
1271
|
+
]).filter((s) => !excludedAppSources.includes(s.context.name) && (!!s.urls?.length || !!s.fetch)).map((s) => {
|
|
1209
1272
|
s.sourceType = "app";
|
|
1210
1273
|
return s;
|
|
1211
1274
|
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URLs from the installed content module's page collections.
|
|
3
|
+
*
|
|
4
|
+
* One route for every provider. `#nuxtseo/content` normalizes the manifest shape
|
|
5
|
+
* and the query builder; the `sitemap` field on each entry is written by the
|
|
6
|
+
* module's `content:file:afterParse` hook.
|
|
7
|
+
*/
|
|
8
|
+
declare const _default: any;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as contentRuntime from "#nuxtseo/content";
|
|
2
|
+
import { defineEventHandler } from "#nuxtseo/h3";
|
|
3
|
+
import { filters } from "#sitemap/content-filters";
|
|
4
|
+
import { onUrlFns } from "#sitemap/content-on-url";
|
|
5
|
+
const { listPageCollections, provider, queryPages } = contentRuntime;
|
|
6
|
+
export default defineEventHandler(async (e) => {
|
|
7
|
+
const collections = (await listPageCollections(e)).filter((collection) => collection.inSitemap && collection.hasField("sitemap")).map((collection) => collection.name);
|
|
8
|
+
const results = await Promise.all(collections.map(async (collection) => {
|
|
9
|
+
const needsAllFields = filters?.has(collection) || onUrlFns?.has(collection);
|
|
10
|
+
const query = queryPages(e, collection).where("path", "IS NOT NULL").where("sitemap", "IS NOT NULL");
|
|
11
|
+
if (!needsAllFields)
|
|
12
|
+
query.select("path", "sitemap");
|
|
13
|
+
try {
|
|
14
|
+
const entries = await query.all();
|
|
15
|
+
const filter = filters?.get(collection);
|
|
16
|
+
return { collection, entries: filter ? entries.filter(filter) : entries };
|
|
17
|
+
} catch (err) {
|
|
18
|
+
const hint = provider === "nuxt-content-v3" ? " On serverless the content DB is restored from a prerendered sql_dump.txt that isn't readable inside the function (nuxt/content#3805). Fix: prerender the sitemap so content URLs resolve at build, or configure a runtime database (D1/Turso/Postgres)." : "";
|
|
19
|
+
console.error(`[@nuxtjs/sitemap] Couldn't query content collection "${collection}" for the sitemap, so its URLs will be missing.${hint}`, err);
|
|
20
|
+
return { collection, entries: [] };
|
|
21
|
+
}
|
|
22
|
+
}));
|
|
23
|
+
return results.flatMap(({ collection, entries }) => {
|
|
24
|
+
const onUrl = onUrlFns?.get(collection);
|
|
25
|
+
return entries.filter((entry) => entry.sitemap !== false && entry.path && !entry.path.endsWith(".navigation")).map((entry) => {
|
|
26
|
+
const url = {
|
|
27
|
+
loc: entry.path,
|
|
28
|
+
...typeof entry.sitemap === "object" && entry.sitemap ? entry.sitemap : {}
|
|
29
|
+
};
|
|
30
|
+
onUrl?.(url, entry, collection);
|
|
31
|
+
return url;
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -204,7 +204,7 @@ export interface SitemapSourceResolved extends Omit<SitemapSourceBase, 'urls'> {
|
|
|
204
204
|
message: string;
|
|
205
205
|
}[];
|
|
206
206
|
}
|
|
207
|
-
export type AppSourceContext = 'nuxt:pages' | 'nuxt:prerender' | 'nuxt:route-rules' | '@nuxtjs/i18n:pages' | 'nuxt-i18n-micro:pages' | '@nuxt/content@v2:urls' | '@nuxt/content@v3:urls';
|
|
207
|
+
export type AppSourceContext = 'nuxt:pages' | 'nuxt:prerender' | 'nuxt:route-rules' | '@nuxtjs/i18n:pages' | 'nuxt-i18n-micro:pages' | '@nuxt/content@v2:urls' | '@nuxt/content@v3:urls' | '@harlan-zw/comark-content:urls';
|
|
208
208
|
export type SitemapSourceInput = string | [string, FetchOptions] | SitemapSourceBase | SitemapSourceResolved;
|
|
209
209
|
interface LocaleObject extends Record<string, any> {
|
|
210
210
|
code: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxtjs/sitemap",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.4.0",
|
|
5
5
|
"description": "Powerfully flexible XML Sitemaps that integrate seamlessly, for Nuxt.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -58,42 +58,43 @@
|
|
|
58
58
|
"@nuxt/kit": "^4.5.2",
|
|
59
59
|
"consola": "^3.4.2",
|
|
60
60
|
"defu": "^6.1.7",
|
|
61
|
-
"nuxt-site-config": "^4.2.
|
|
62
|
-
"nuxtseo-shared": "^5.3.
|
|
61
|
+
"nuxt-site-config": "^4.2.3",
|
|
62
|
+
"nuxtseo-shared": "^5.3.14",
|
|
63
63
|
"ofetch": "^1.5.1",
|
|
64
64
|
"pathe": "^2.0.3",
|
|
65
65
|
"pkg-types": "^2.3.1",
|
|
66
66
|
"radix3": "^1.1.2",
|
|
67
67
|
"ufo": "^1.6.4",
|
|
68
68
|
"ultrahtml": "^1.7.0",
|
|
69
|
-
"sitemapd": "^0.2.
|
|
69
|
+
"sitemapd": "^0.2.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@antfu/eslint-config": "^9.3.0",
|
|
73
73
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
74
|
+
"@harlan-zw/comark-content": "^0.1.3",
|
|
74
75
|
"@nuxt/content": "^3.15.2",
|
|
75
|
-
"@nuxt/devtools-kit": "4.0.0-alpha.
|
|
76
|
+
"@nuxt/devtools-kit": "4.0.0-alpha.11",
|
|
76
77
|
"@nuxt/module-builder": "^1.0.3",
|
|
77
78
|
"@nuxt/test-utils": "^4.1.0",
|
|
78
79
|
"@nuxt/ui": "^4.10.0",
|
|
79
80
|
"@nuxtjs/i18n": "^10.6.0",
|
|
80
|
-
"@nuxtjs/robots": "^6.1.
|
|
81
|
+
"@nuxtjs/robots": "^6.1.5",
|
|
81
82
|
"@vue/test-utils": "^2.4.11",
|
|
82
83
|
"better-sqlite3": "^13.0.3",
|
|
83
|
-
"bumpp": "^12.2.
|
|
84
|
+
"bumpp": "^12.2.1",
|
|
84
85
|
"eslint": "^10.8.1",
|
|
85
|
-
"eslint-plugin-harlanzw": "^0.
|
|
86
|
+
"eslint-plugin-harlanzw": "^0.20.0",
|
|
86
87
|
"happy-dom": "^20.11.2",
|
|
87
88
|
"nuxt": "^4.5.2",
|
|
88
89
|
"nuxt-i18n-micro": "^3.28.0",
|
|
89
|
-
"nuxtseo-layer-devtools": "^5.3.
|
|
90
|
+
"nuxtseo-layer-devtools": "^5.3.14",
|
|
90
91
|
"std-env": "^4.2.0",
|
|
91
92
|
"typescript": "6.0.3",
|
|
92
93
|
"unbuild": "^3.6.1",
|
|
93
|
-
"vitest": "^4.1.
|
|
94
|
-
"vue-tsc": "^3.3.
|
|
94
|
+
"vitest": "^4.1.11",
|
|
95
|
+
"vue-tsc": "^3.3.10",
|
|
95
96
|
"zod": "^4.4.3",
|
|
96
|
-
"@nuxtjs/sitemap": "8.
|
|
97
|
+
"@nuxtjs/sitemap": "8.4.0"
|
|
97
98
|
},
|
|
98
99
|
"scripts": {
|
|
99
100
|
"lint": "eslint .",
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { queryCollection } from "@nuxt/content/server";
|
|
2
|
-
import manifest from "#content/manifest";
|
|
3
|
-
import { defineEventHandler } from "#nuxtseo/h3";
|
|
4
|
-
import { filters } from "#sitemap/content-filters";
|
|
5
|
-
import { onUrlFns } from "#sitemap/content-on-url";
|
|
6
|
-
export default defineEventHandler(async (e) => {
|
|
7
|
-
const collections = [];
|
|
8
|
-
for (const collection in manifest) {
|
|
9
|
-
if (manifest[collection].fields.sitemap)
|
|
10
|
-
collections.push(collection);
|
|
11
|
-
}
|
|
12
|
-
const contentList = [];
|
|
13
|
-
for (const collection of collections) {
|
|
14
|
-
const needsAllFields = filters?.has(collection) || onUrlFns?.has(collection);
|
|
15
|
-
const query = queryCollection(e, collection).where("path", "IS NOT NULL").where("sitemap", "IS NOT NULL");
|
|
16
|
-
if (!needsAllFields)
|
|
17
|
-
query.select("path", "sitemap");
|
|
18
|
-
contentList.push(
|
|
19
|
-
query.all().then((results2) => {
|
|
20
|
-
const filter = filters?.get(collection);
|
|
21
|
-
return { collection, entries: filter ? results2.filter(filter) : results2 };
|
|
22
|
-
}).catch((err) => {
|
|
23
|
-
console.error(`[@nuxtjs/sitemap] Couldn't query @nuxt/content collection "${collection}" for the sitemap, so its URLs will be missing. On serverless the content DB is restored from a prerendered sql_dump.txt that isn't readable inside the function (nuxt/content#3805). Fix: prerender the sitemap so content URLs resolve at build, or configure a runtime database (D1/Turso/Postgres).`, err);
|
|
24
|
-
return { collection, entries: [] };
|
|
25
|
-
})
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
const results = await Promise.all(contentList);
|
|
29
|
-
return results.flatMap(({ collection, entries }) => {
|
|
30
|
-
const onUrl = onUrlFns?.get(collection);
|
|
31
|
-
return entries.filter((c) => c.sitemap !== false && c.path && !c.path.endsWith(".navigation")).map((c) => {
|
|
32
|
-
const url = {
|
|
33
|
-
loc: c.path,
|
|
34
|
-
...typeof c.sitemap === "object" ? c.sitemap : {}
|
|
35
|
-
};
|
|
36
|
-
onUrl?.(url, c, collection);
|
|
37
|
-
return url;
|
|
38
|
-
});
|
|
39
|
-
}).filter(Boolean);
|
|
40
|
-
});
|