@onruntime/next-sitemap 0.8.0 → 0.9.1

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.
@@ -27,14 +27,55 @@ function _interopNamespace(e) {
27
27
  var childProcess__namespace = /*#__PURE__*/_interopNamespace(childProcess);
28
28
 
29
29
  // src/app/index.ts
30
+ var JS_EXTENSIONS = /* @__PURE__ */ new Set([
31
+ ".js",
32
+ ".cjs",
33
+ ".mjs",
34
+ ".jsx",
35
+ ".ts",
36
+ ".cts",
37
+ ".mts",
38
+ ".tsx",
39
+ ".json",
40
+ ".node"
41
+ ]);
30
42
  var NO_STATIC_PARAMS = "NO_STATIC_PARAMS";
31
43
  var spawnProcess = childProcess__namespace.spawn;
32
44
  var __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
33
45
  var paramsCache = /* @__PURE__ */ new Map();
34
46
  var isDev = process.env.NODE_ENV === "development";
47
+ function resolveFilePath(directory, fileKey) {
48
+ if (fileKey.startsWith("./")) {
49
+ return path.join(directory, fileKey.replace("./", ""));
50
+ }
51
+ const basePath = fileKey === "/" ? "/index" : fileKey;
52
+ const jsPath = path.join(directory, basePath + ".js");
53
+ if (fs.existsSync(jsPath)) {
54
+ return jsPath;
55
+ }
56
+ for (const ext of JS_EXTENSIONS) {
57
+ const sourcePath = path.join(directory, basePath + ext);
58
+ if (fs.existsSync(sourcePath)) {
59
+ return sourcePath;
60
+ }
61
+ }
62
+ for (const ext of JS_EXTENSIONS) {
63
+ const indexPath = path.join(directory, basePath, "index" + ext);
64
+ if (fs.existsSync(indexPath)) {
65
+ return indexPath;
66
+ }
67
+ }
68
+ return null;
69
+ }
35
70
  async function executeWorker(directory, fileKey, debug) {
36
- const absolutePath = path.join(directory, fileKey.replace("./", ""));
71
+ const absolutePath = resolveFilePath(directory, fileKey);
37
72
  const projectRoot = process.cwd();
73
+ if (!absolutePath) {
74
+ if (debug) {
75
+ console.warn(`[next-sitemap] Could not resolve file path for ${fileKey} in ${directory}`);
76
+ }
77
+ return null;
78
+ }
38
79
  const distRoot = path.join(__dirname$1, "..");
39
80
  const workerPath = path.join(distRoot, "worker.cjs");
40
81
  const loaderPath = path.join(distRoot, "loader.js");
@@ -232,7 +273,8 @@ function buildUrl(baseUrl, pathname, locale, defaultLocale) {
232
273
  if (!locale || locale === defaultLocale) {
233
274
  return `${baseUrl}${normalizedPath}`;
234
275
  }
235
- return `${baseUrl}/${locale}${normalizedPath}`;
276
+ const pathSuffix = pathname === "/" ? "" : normalizedPath;
277
+ return `${baseUrl}/${locale}${pathSuffix}`;
236
278
  }
237
279
  function generateSitemapXml(entries, options) {
238
280
  const { poweredBy = true } = options || {};
package/dist/app/index.js CHANGED
@@ -4,14 +4,55 @@ import * as childProcess from 'child_process';
4
4
  import { fileURLToPath } from 'url';
5
5
 
6
6
  // src/app/index.ts
7
+ var JS_EXTENSIONS = /* @__PURE__ */ new Set([
8
+ ".js",
9
+ ".cjs",
10
+ ".mjs",
11
+ ".jsx",
12
+ ".ts",
13
+ ".cts",
14
+ ".mts",
15
+ ".tsx",
16
+ ".json",
17
+ ".node"
18
+ ]);
7
19
  var NO_STATIC_PARAMS = "NO_STATIC_PARAMS";
8
20
  var spawnProcess = childProcess.spawn;
9
21
  var __dirname$1 = dirname(fileURLToPath(import.meta.url));
10
22
  var paramsCache = /* @__PURE__ */ new Map();
11
23
  var isDev = process.env.NODE_ENV === "development";
24
+ function resolveFilePath(directory, fileKey) {
25
+ if (fileKey.startsWith("./")) {
26
+ return join(directory, fileKey.replace("./", ""));
27
+ }
28
+ const basePath = fileKey === "/" ? "/index" : fileKey;
29
+ const jsPath = join(directory, basePath + ".js");
30
+ if (existsSync(jsPath)) {
31
+ return jsPath;
32
+ }
33
+ for (const ext of JS_EXTENSIONS) {
34
+ const sourcePath = join(directory, basePath + ext);
35
+ if (existsSync(sourcePath)) {
36
+ return sourcePath;
37
+ }
38
+ }
39
+ for (const ext of JS_EXTENSIONS) {
40
+ const indexPath = join(directory, basePath, "index" + ext);
41
+ if (existsSync(indexPath)) {
42
+ return indexPath;
43
+ }
44
+ }
45
+ return null;
46
+ }
12
47
  async function executeWorker(directory, fileKey, debug) {
13
- const absolutePath = join(directory, fileKey.replace("./", ""));
48
+ const absolutePath = resolveFilePath(directory, fileKey);
14
49
  const projectRoot = process.cwd();
50
+ if (!absolutePath) {
51
+ if (debug) {
52
+ console.warn(`[next-sitemap] Could not resolve file path for ${fileKey} in ${directory}`);
53
+ }
54
+ return null;
55
+ }
15
56
  const distRoot = join(__dirname$1, "..");
16
57
  const workerPath = join(distRoot, "worker.cjs");
17
58
  const loaderPath = join(distRoot, "loader.js");
@@ -209,7 +250,8 @@ function buildUrl(baseUrl, pathname, locale, defaultLocale) {
209
250
  if (!locale || locale === defaultLocale) {
210
251
  return `${baseUrl}${normalizedPath}`;
211
252
  }
212
- return `${baseUrl}/${locale}${normalizedPath}`;
253
+ const pathSuffix = pathname === "/" ? "" : normalizedPath;
254
+ return `${baseUrl}/${locale}${pathSuffix}`;
213
255
  }
214
256
  function generateSitemapXml(entries, options) {
215
257
  const { poweredBy = true } = options || {};
package/dist/index.cjs CHANGED
@@ -44,9 +44,38 @@ var spawnProcess = childProcess__namespace.spawn;
44
44
  var __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
45
45
  var paramsCache = /* @__PURE__ */ new Map();
46
46
  var isDev = process.env.NODE_ENV === "development";
47
+ function resolveFilePath(directory, fileKey) {
48
+ if (fileKey.startsWith("./")) {
49
+ return path.join(directory, fileKey.replace("./", ""));
50
+ }
51
+ const basePath = fileKey === "/" ? "/index" : fileKey;
52
+ const jsPath = path.join(directory, basePath + ".js");
53
+ if (fs.existsSync(jsPath)) {
54
+ return jsPath;
55
+ }
56
+ for (const ext of JS_EXTENSIONS) {
57
+ const sourcePath = path.join(directory, basePath + ext);
58
+ if (fs.existsSync(sourcePath)) {
59
+ return sourcePath;
60
+ }
61
+ }
62
+ for (const ext of JS_EXTENSIONS) {
63
+ const indexPath = path.join(directory, basePath, "index" + ext);
64
+ if (fs.existsSync(indexPath)) {
65
+ return indexPath;
66
+ }
67
+ }
68
+ return null;
69
+ }
47
70
  async function executeWorker(directory, fileKey, debug) {
48
- const absolutePath = path.join(directory, fileKey.replace("./", ""));
71
+ const absolutePath = resolveFilePath(directory, fileKey);
49
72
  const projectRoot = process.cwd();
73
+ if (!absolutePath) {
74
+ if (debug) {
75
+ console.warn(`[next-sitemap] Could not resolve file path for ${fileKey} in ${directory}`);
76
+ }
77
+ return null;
78
+ }
50
79
  const distRoot = path.join(__dirname$1, "..");
51
80
  const workerPath = path.join(distRoot, "worker.cjs");
52
81
  const loaderPath = path.join(distRoot, "loader.js");
@@ -244,7 +273,8 @@ function buildUrl(baseUrl, pathname, locale, defaultLocale) {
244
273
  if (!locale || locale === defaultLocale) {
245
274
  return `${baseUrl}${normalizedPath}`;
246
275
  }
247
- return `${baseUrl}/${locale}${normalizedPath}`;
276
+ const pathSuffix = pathname === "/" ? "" : normalizedPath;
277
+ return `${baseUrl}/${locale}${pathSuffix}`;
248
278
  }
249
279
  function generateSitemapXml(entries, options) {
250
280
  const { poweredBy = true } = options || {};
package/dist/index.js CHANGED
@@ -21,9 +21,38 @@ var spawnProcess = childProcess.spawn;
21
21
  var __dirname$1 = dirname(fileURLToPath(import.meta.url));
22
22
  var paramsCache = /* @__PURE__ */ new Map();
23
23
  var isDev = process.env.NODE_ENV === "development";
24
+ function resolveFilePath(directory, fileKey) {
25
+ if (fileKey.startsWith("./")) {
26
+ return join(directory, fileKey.replace("./", ""));
27
+ }
28
+ const basePath = fileKey === "/" ? "/index" : fileKey;
29
+ const jsPath = join(directory, basePath + ".js");
30
+ if (existsSync(jsPath)) {
31
+ return jsPath;
32
+ }
33
+ for (const ext of JS_EXTENSIONS) {
34
+ const sourcePath = join(directory, basePath + ext);
35
+ if (existsSync(sourcePath)) {
36
+ return sourcePath;
37
+ }
38
+ }
39
+ for (const ext of JS_EXTENSIONS) {
40
+ const indexPath = join(directory, basePath, "index" + ext);
41
+ if (existsSync(indexPath)) {
42
+ return indexPath;
43
+ }
44
+ }
45
+ return null;
46
+ }
24
47
  async function executeWorker(directory, fileKey, debug) {
25
- const absolutePath = join(directory, fileKey.replace("./", ""));
48
+ const absolutePath = resolveFilePath(directory, fileKey);
26
49
  const projectRoot = process.cwd();
50
+ if (!absolutePath) {
51
+ if (debug) {
52
+ console.warn(`[next-sitemap] Could not resolve file path for ${fileKey} in ${directory}`);
53
+ }
54
+ return null;
55
+ }
27
56
  const distRoot = join(__dirname$1, "..");
28
57
  const workerPath = join(distRoot, "worker.cjs");
29
58
  const loaderPath = join(distRoot, "loader.js");
@@ -221,7 +250,8 @@ function buildUrl(baseUrl, pathname, locale, defaultLocale) {
221
250
  if (!locale || locale === defaultLocale) {
222
251
  return `${baseUrl}${normalizedPath}`;
223
252
  }
224
- return `${baseUrl}/${locale}${normalizedPath}`;
253
+ const pathSuffix = pathname === "/" ? "" : normalizedPath;
254
+ return `${baseUrl}/${locale}${pathSuffix}`;
225
255
  }
226
256
  function generateSitemapXml(entries, options) {
227
257
  const { poweredBy = true } = options || {};
@@ -27,14 +27,55 @@ function _interopNamespace(e) {
27
27
  var childProcess__namespace = /*#__PURE__*/_interopNamespace(childProcess);
28
28
 
29
29
  // src/pages/index.ts
30
+ var JS_EXTENSIONS = /* @__PURE__ */ new Set([
31
+ ".js",
32
+ ".cjs",
33
+ ".mjs",
34
+ ".jsx",
35
+ ".ts",
36
+ ".cts",
37
+ ".mts",
38
+ ".tsx",
39
+ ".json",
40
+ ".node"
41
+ ]);
30
42
  var NO_STATIC_PARAMS = "NO_STATIC_PARAMS";
31
43
  var spawnProcess = childProcess__namespace.spawn;
32
44
  var __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
33
45
  var paramsCache = /* @__PURE__ */ new Map();
34
46
  var isDev = process.env.NODE_ENV === "development";
47
+ function resolveFilePath(directory, fileKey) {
48
+ if (fileKey.startsWith("./")) {
49
+ return path.join(directory, fileKey.replace("./", ""));
50
+ }
51
+ const basePath = fileKey === "/" ? "/index" : fileKey;
52
+ const jsPath = path.join(directory, basePath + ".js");
53
+ if (fs.existsSync(jsPath)) {
54
+ return jsPath;
55
+ }
56
+ for (const ext of JS_EXTENSIONS) {
57
+ const sourcePath = path.join(directory, basePath + ext);
58
+ if (fs.existsSync(sourcePath)) {
59
+ return sourcePath;
60
+ }
61
+ }
62
+ for (const ext of JS_EXTENSIONS) {
63
+ const indexPath = path.join(directory, basePath, "index" + ext);
64
+ if (fs.existsSync(indexPath)) {
65
+ return indexPath;
66
+ }
67
+ }
68
+ return null;
69
+ }
35
70
  async function executeWorker(directory, fileKey, debug) {
36
- const absolutePath = path.join(directory, fileKey.replace("./", ""));
71
+ const absolutePath = resolveFilePath(directory, fileKey);
37
72
  const projectRoot = process.cwd();
73
+ if (!absolutePath) {
74
+ if (debug) {
75
+ console.warn(`[next-sitemap] Could not resolve file path for ${fileKey} in ${directory}`);
76
+ }
77
+ return null;
78
+ }
38
79
  const distRoot = path.join(__dirname$1, "..");
39
80
  const workerPath = path.join(distRoot, "worker.cjs");
40
81
  const loaderPath = path.join(distRoot, "loader.js");
@@ -232,7 +273,8 @@ function buildUrl(baseUrl, pathname, locale, defaultLocale) {
232
273
  if (!locale || locale === defaultLocale) {
233
274
  return `${baseUrl}${normalizedPath}`;
234
275
  }
235
- return `${baseUrl}/${locale}${normalizedPath}`;
276
+ const pathSuffix = pathname === "/" ? "" : normalizedPath;
277
+ return `${baseUrl}/${locale}${pathSuffix}`;
236
278
  }
237
279
  function generateSitemapXml(entries, options) {
238
280
  const { poweredBy = true } = options || {};
@@ -334,6 +376,46 @@ function generateRobotsTxt(config) {
334
376
  }
335
377
 
336
378
  // src/pages/index.ts
379
+ function readRoutesManifest(debug) {
380
+ const manifestPath = path.join(process.cwd(), ".next", "routes-manifest.json");
381
+ if (!fs.existsSync(manifestPath)) {
382
+ if (debug) {
383
+ console.log(`[next-sitemap] routes-manifest.json not found at ${manifestPath}`);
384
+ }
385
+ return null;
386
+ }
387
+ try {
388
+ const content = fs.readFileSync(manifestPath, "utf-8");
389
+ return JSON.parse(content);
390
+ } catch (err) {
391
+ if (debug) {
392
+ console.warn(`[next-sitemap] Failed to read routes-manifest.json:`, err);
393
+ }
394
+ return null;
395
+ }
396
+ }
397
+ function extractRoutesFromManifest(manifest) {
398
+ const routes = [];
399
+ for (const route of manifest.staticRoutes) {
400
+ if (route.page.startsWith("/api/")) continue;
401
+ routes.push({
402
+ pathname: route.page,
403
+ dynamicSegments: [],
404
+ fileKey: route.page
405
+ });
406
+ }
407
+ for (const route of manifest.dynamicRoutes) {
408
+ if (route.page.startsWith("/api/")) continue;
409
+ if (route.page.includes("[...")) continue;
410
+ const dynamicSegments = route.page.match(/\[([^\]]+)\]/g)?.map((s) => s.slice(1, -1)) ?? [];
411
+ routes.push({
412
+ pathname: route.page,
413
+ dynamicSegments,
414
+ fileKey: route.page
415
+ });
416
+ }
417
+ return routes;
418
+ }
337
419
  function findPageFiles(dir, baseDir = dir) {
338
420
  const files = [];
339
421
  try {
@@ -359,7 +441,7 @@ function resolvePagesDirectory(pagesDirectory) {
359
441
  const srcPages = path.join(process.cwd(), "src/pages");
360
442
  return fs.existsSync(srcPages) ? srcPages : path.join(process.cwd(), "pages");
361
443
  }
362
- function extractRoutes(pageKeys, localeSegment) {
444
+ function extractRoutesFromFiles(pageKeys, localeSegment) {
363
445
  const routes = [];
364
446
  for (const key of pageKeys) {
365
447
  if (key.includes("[...")) continue;
@@ -380,17 +462,39 @@ function extractRoutes(pageKeys, localeSegment) {
380
462
  }
381
463
  return routes;
382
464
  }
465
+ function getRoutes(pagesDirectory, localeSegment, debug) {
466
+ const manifest = readRoutesManifest(debug);
467
+ if (manifest) {
468
+ if (debug) {
469
+ console.log(`[next-sitemap] Using routes-manifest.json for route discovery`);
470
+ }
471
+ return extractRoutesFromManifest(manifest);
472
+ }
473
+ if (debug) {
474
+ console.log(`[next-sitemap] Falling back to file scanning for route discovery`);
475
+ }
476
+ const pagesDir = resolvePagesDirectory(pagesDirectory);
477
+ const pageKeys = findPageFiles(pagesDir);
478
+ return extractRoutesFromFiles(pageKeys, localeSegment);
479
+ }
480
+ function getWorkerDirectory(pagesDirectory) {
481
+ const compiledDir = path.join(process.cwd(), ".next", "server", "pages");
482
+ if (fs.existsSync(compiledDir)) {
483
+ return compiledDir;
484
+ }
485
+ return resolvePagesDirectory(pagesDirectory);
486
+ }
383
487
  function createSitemapIndexApiHandler(options) {
384
488
  const { urlsPerSitemap = 5e3, additionalSitemaps, exclude, debug = false } = options;
385
489
  const localeSegment = options.localeSegment ?? "";
386
- const pagesDir = resolvePagesDirectory(options.pagesDirectory);
387
- const pageKeys = findPageFiles(pagesDir);
388
- const routes = extractRoutes(pageKeys, localeSegment);
389
490
  return async function handler(_req, res) {
491
+ const routes = getRoutes(options.pagesDirectory, localeSegment, debug);
492
+ const workerDir = getWorkerDirectory(options.pagesDirectory);
390
493
  if (debug) {
391
494
  console.log(`[next-sitemap] Found ${routes.length} routes`);
495
+ console.log(`[next-sitemap] Worker directory: ${workerDir}`);
392
496
  }
393
- const allPaths = await generateAllPaths(routes, pagesDir, debug);
497
+ const allPaths = await generateAllPaths(routes, workerDir, debug);
394
498
  const filteredPaths = allPaths.filter((p) => !shouldExclude(p, exclude));
395
499
  const sitemapCount = Math.max(1, Math.ceil(filteredPaths.length / urlsPerSitemap));
396
500
  res.setHeader("Content-Type", "application/xml");
@@ -402,11 +506,10 @@ function createSitemapIndexApiHandler(options) {
402
506
  function createSitemapApiHandler(options) {
403
507
  const { urlsPerSitemap = 5e3, exclude, debug = false } = options;
404
508
  const localeSegment = options.localeSegment ?? "";
405
- const pagesDir = resolvePagesDirectory(options.pagesDirectory);
406
- const pageKeys = findPageFiles(pagesDir);
407
- const routes = extractRoutes(pageKeys, localeSegment);
408
509
  const getFilteredPaths = async () => {
409
- const allPaths = await generateAllPaths(routes, pagesDir, debug);
510
+ const routes = getRoutes(options.pagesDirectory, localeSegment, debug);
511
+ const workerDir = getWorkerDirectory(options.pagesDirectory);
512
+ const allPaths = await generateAllPaths(routes, workerDir, debug);
410
513
  return allPaths.filter((p) => !shouldExclude(p, exclude));
411
514
  };
412
515
  return async function handler(req, res) {
@@ -422,10 +525,9 @@ function createSitemapApiHandler(options) {
422
525
  async function getSitemapStaticPaths(options) {
423
526
  const { urlsPerSitemap = 5e3, exclude, debug = false } = options;
424
527
  const localeSegment = options.localeSegment ?? "";
425
- const pagesDir = resolvePagesDirectory(options.pagesDirectory);
426
- const pageKeys = findPageFiles(pagesDir);
427
- const routes = extractRoutes(pageKeys, localeSegment);
428
- const allPaths = await generateAllPaths(routes, pagesDir, debug);
528
+ const routes = getRoutes(options.pagesDirectory, localeSegment, debug);
529
+ const workerDir = getWorkerDirectory(options.pagesDirectory);
530
+ const allPaths = await generateAllPaths(routes, workerDir, debug);
429
531
  const filteredPaths = allPaths.filter((pathname) => !shouldExclude(pathname, exclude));
430
532
  const sitemapCount = Math.max(1, Math.ceil(filteredPaths.length / urlsPerSitemap));
431
533
  return {
@@ -94,6 +94,7 @@ interface CreateSitemapApiHandlerOptions extends SitemapConfig {
94
94
  * Path to the pages directory to scan for page files.
95
95
  * Can be absolute or relative to process.cwd().
96
96
  * If not provided, auto-detects src/pages or pages.
97
+ * @deprecated Use routes-manifest.json from .next directory instead
97
98
  */
98
99
  pagesDirectory?: string;
99
100
  }
@@ -94,6 +94,7 @@ interface CreateSitemapApiHandlerOptions extends SitemapConfig {
94
94
  * Path to the pages directory to scan for page files.
95
95
  * Can be absolute or relative to process.cwd().
96
96
  * If not provided, auto-detects src/pages or pages.
97
+ * @deprecated Use routes-manifest.json from .next directory instead
97
98
  */
98
99
  pagesDirectory?: string;
99
100
  }
@@ -1,17 +1,58 @@
1
- import { existsSync, readdirSync } from 'fs';
1
+ import { existsSync, readFileSync, readdirSync } from 'fs';
2
2
  import { dirname, join, isAbsolute, relative, delimiter } from 'path';
3
3
  import * as childProcess from 'child_process';
4
4
  import { fileURLToPath } from 'url';
5
5
 
6
6
  // src/pages/index.ts
7
+ var JS_EXTENSIONS = /* @__PURE__ */ new Set([
8
+ ".js",
9
+ ".cjs",
10
+ ".mjs",
11
+ ".jsx",
12
+ ".ts",
13
+ ".cts",
14
+ ".mts",
15
+ ".tsx",
16
+ ".json",
17
+ ".node"
18
+ ]);
7
19
  var NO_STATIC_PARAMS = "NO_STATIC_PARAMS";
8
20
  var spawnProcess = childProcess.spawn;
9
21
  var __dirname$1 = dirname(fileURLToPath(import.meta.url));
10
22
  var paramsCache = /* @__PURE__ */ new Map();
11
23
  var isDev = process.env.NODE_ENV === "development";
24
+ function resolveFilePath(directory, fileKey) {
25
+ if (fileKey.startsWith("./")) {
26
+ return join(directory, fileKey.replace("./", ""));
27
+ }
28
+ const basePath = fileKey === "/" ? "/index" : fileKey;
29
+ const jsPath = join(directory, basePath + ".js");
30
+ if (existsSync(jsPath)) {
31
+ return jsPath;
32
+ }
33
+ for (const ext of JS_EXTENSIONS) {
34
+ const sourcePath = join(directory, basePath + ext);
35
+ if (existsSync(sourcePath)) {
36
+ return sourcePath;
37
+ }
38
+ }
39
+ for (const ext of JS_EXTENSIONS) {
40
+ const indexPath = join(directory, basePath, "index" + ext);
41
+ if (existsSync(indexPath)) {
42
+ return indexPath;
43
+ }
44
+ }
45
+ return null;
46
+ }
12
47
  async function executeWorker(directory, fileKey, debug) {
13
- const absolutePath = join(directory, fileKey.replace("./", ""));
48
+ const absolutePath = resolveFilePath(directory, fileKey);
14
49
  const projectRoot = process.cwd();
50
+ if (!absolutePath) {
51
+ if (debug) {
52
+ console.warn(`[next-sitemap] Could not resolve file path for ${fileKey} in ${directory}`);
53
+ }
54
+ return null;
55
+ }
15
56
  const distRoot = join(__dirname$1, "..");
16
57
  const workerPath = join(distRoot, "worker.cjs");
17
58
  const loaderPath = join(distRoot, "loader.js");
@@ -209,7 +250,8 @@ function buildUrl(baseUrl, pathname, locale, defaultLocale) {
209
250
  if (!locale || locale === defaultLocale) {
210
251
  return `${baseUrl}${normalizedPath}`;
211
252
  }
212
- return `${baseUrl}/${locale}${normalizedPath}`;
253
+ const pathSuffix = pathname === "/" ? "" : normalizedPath;
254
+ return `${baseUrl}/${locale}${pathSuffix}`;
213
255
  }
214
256
  function generateSitemapXml(entries, options) {
215
257
  const { poweredBy = true } = options || {};
@@ -311,6 +353,46 @@ function generateRobotsTxt(config) {
311
353
  }
312
354
 
313
355
  // src/pages/index.ts
356
+ function readRoutesManifest(debug) {
357
+ const manifestPath = join(process.cwd(), ".next", "routes-manifest.json");
358
+ if (!existsSync(manifestPath)) {
359
+ if (debug) {
360
+ console.log(`[next-sitemap] routes-manifest.json not found at ${manifestPath}`);
361
+ }
362
+ return null;
363
+ }
364
+ try {
365
+ const content = readFileSync(manifestPath, "utf-8");
366
+ return JSON.parse(content);
367
+ } catch (err) {
368
+ if (debug) {
369
+ console.warn(`[next-sitemap] Failed to read routes-manifest.json:`, err);
370
+ }
371
+ return null;
372
+ }
373
+ }
374
+ function extractRoutesFromManifest(manifest) {
375
+ const routes = [];
376
+ for (const route of manifest.staticRoutes) {
377
+ if (route.page.startsWith("/api/")) continue;
378
+ routes.push({
379
+ pathname: route.page,
380
+ dynamicSegments: [],
381
+ fileKey: route.page
382
+ });
383
+ }
384
+ for (const route of manifest.dynamicRoutes) {
385
+ if (route.page.startsWith("/api/")) continue;
386
+ if (route.page.includes("[...")) continue;
387
+ const dynamicSegments = route.page.match(/\[([^\]]+)\]/g)?.map((s) => s.slice(1, -1)) ?? [];
388
+ routes.push({
389
+ pathname: route.page,
390
+ dynamicSegments,
391
+ fileKey: route.page
392
+ });
393
+ }
394
+ return routes;
395
+ }
314
396
  function findPageFiles(dir, baseDir = dir) {
315
397
  const files = [];
316
398
  try {
@@ -336,7 +418,7 @@ function resolvePagesDirectory(pagesDirectory) {
336
418
  const srcPages = join(process.cwd(), "src/pages");
337
419
  return existsSync(srcPages) ? srcPages : join(process.cwd(), "pages");
338
420
  }
339
- function extractRoutes(pageKeys, localeSegment) {
421
+ function extractRoutesFromFiles(pageKeys, localeSegment) {
340
422
  const routes = [];
341
423
  for (const key of pageKeys) {
342
424
  if (key.includes("[...")) continue;
@@ -357,17 +439,39 @@ function extractRoutes(pageKeys, localeSegment) {
357
439
  }
358
440
  return routes;
359
441
  }
442
+ function getRoutes(pagesDirectory, localeSegment, debug) {
443
+ const manifest = readRoutesManifest(debug);
444
+ if (manifest) {
445
+ if (debug) {
446
+ console.log(`[next-sitemap] Using routes-manifest.json for route discovery`);
447
+ }
448
+ return extractRoutesFromManifest(manifest);
449
+ }
450
+ if (debug) {
451
+ console.log(`[next-sitemap] Falling back to file scanning for route discovery`);
452
+ }
453
+ const pagesDir = resolvePagesDirectory(pagesDirectory);
454
+ const pageKeys = findPageFiles(pagesDir);
455
+ return extractRoutesFromFiles(pageKeys, localeSegment);
456
+ }
457
+ function getWorkerDirectory(pagesDirectory) {
458
+ const compiledDir = join(process.cwd(), ".next", "server", "pages");
459
+ if (existsSync(compiledDir)) {
460
+ return compiledDir;
461
+ }
462
+ return resolvePagesDirectory(pagesDirectory);
463
+ }
360
464
  function createSitemapIndexApiHandler(options) {
361
465
  const { urlsPerSitemap = 5e3, additionalSitemaps, exclude, debug = false } = options;
362
466
  const localeSegment = options.localeSegment ?? "";
363
- const pagesDir = resolvePagesDirectory(options.pagesDirectory);
364
- const pageKeys = findPageFiles(pagesDir);
365
- const routes = extractRoutes(pageKeys, localeSegment);
366
467
  return async function handler(_req, res) {
468
+ const routes = getRoutes(options.pagesDirectory, localeSegment, debug);
469
+ const workerDir = getWorkerDirectory(options.pagesDirectory);
367
470
  if (debug) {
368
471
  console.log(`[next-sitemap] Found ${routes.length} routes`);
472
+ console.log(`[next-sitemap] Worker directory: ${workerDir}`);
369
473
  }
370
- const allPaths = await generateAllPaths(routes, pagesDir, debug);
474
+ const allPaths = await generateAllPaths(routes, workerDir, debug);
371
475
  const filteredPaths = allPaths.filter((p) => !shouldExclude(p, exclude));
372
476
  const sitemapCount = Math.max(1, Math.ceil(filteredPaths.length / urlsPerSitemap));
373
477
  res.setHeader("Content-Type", "application/xml");
@@ -379,11 +483,10 @@ function createSitemapIndexApiHandler(options) {
379
483
  function createSitemapApiHandler(options) {
380
484
  const { urlsPerSitemap = 5e3, exclude, debug = false } = options;
381
485
  const localeSegment = options.localeSegment ?? "";
382
- const pagesDir = resolvePagesDirectory(options.pagesDirectory);
383
- const pageKeys = findPageFiles(pagesDir);
384
- const routes = extractRoutes(pageKeys, localeSegment);
385
486
  const getFilteredPaths = async () => {
386
- const allPaths = await generateAllPaths(routes, pagesDir, debug);
487
+ const routes = getRoutes(options.pagesDirectory, localeSegment, debug);
488
+ const workerDir = getWorkerDirectory(options.pagesDirectory);
489
+ const allPaths = await generateAllPaths(routes, workerDir, debug);
387
490
  return allPaths.filter((p) => !shouldExclude(p, exclude));
388
491
  };
389
492
  return async function handler(req, res) {
@@ -399,10 +502,9 @@ function createSitemapApiHandler(options) {
399
502
  async function getSitemapStaticPaths(options) {
400
503
  const { urlsPerSitemap = 5e3, exclude, debug = false } = options;
401
504
  const localeSegment = options.localeSegment ?? "";
402
- const pagesDir = resolvePagesDirectory(options.pagesDirectory);
403
- const pageKeys = findPageFiles(pagesDir);
404
- const routes = extractRoutes(pageKeys, localeSegment);
405
- const allPaths = await generateAllPaths(routes, pagesDir, debug);
505
+ const routes = getRoutes(options.pagesDirectory, localeSegment, debug);
506
+ const workerDir = getWorkerDirectory(options.pagesDirectory);
507
+ const allPaths = await generateAllPaths(routes, workerDir, debug);
406
508
  const filteredPaths = allPaths.filter((pathname) => !shouldExclude(pathname, exclude));
407
509
  const sitemapCount = Math.max(1, Math.ceil(filteredPaths.length / urlsPerSitemap));
408
510
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onruntime/next-sitemap",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Dynamic sitemap generation for Next.js with automatic route discovery",
5
5
  "author": "onRuntime Studio <contact@onruntime.com>",
6
6
  "repository": {