@onruntime/next-sitemap 0.4.1 → 0.5.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/README.md +42 -0
- package/dist/pages/index.cjs +47 -0
- package/dist/pages/index.d.cts +27 -2
- package/dist/pages/index.d.ts +27 -2
- package/dist/pages/index.js +46 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Dynamic sitemap generation for Next.js with automatic route discovery.
|
|
|
17
17
|
- Multi-sitemap support with sitemap index (for sites with >50,000 URLs)
|
|
18
18
|
- hreflang alternates for i18n
|
|
19
19
|
- Fully static generation (SSG)
|
|
20
|
+
- robots.txt generation with Next.js `MetadataRoute.Robots` compatibility
|
|
20
21
|
|
|
21
22
|
## Installation
|
|
22
23
|
|
|
@@ -354,6 +355,47 @@ export async function GET() {
|
|
|
354
355
|
</urlset>
|
|
355
356
|
```
|
|
356
357
|
|
|
358
|
+
## Robots.txt (Pages Router)
|
|
359
|
+
|
|
360
|
+
For Pages Router, use `createRobotsApiHandler` to generate a `robots.txt` file. The configuration uses the same format as [Next.js `MetadataRoute.Robots`](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/robots).
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
// pages/api/robots.txt.ts
|
|
364
|
+
import { createRobotsApiHandler } from "@onruntime/next-sitemap/pages";
|
|
365
|
+
|
|
366
|
+
export default createRobotsApiHandler({
|
|
367
|
+
rules: {
|
|
368
|
+
userAgent: "*",
|
|
369
|
+
allow: "/",
|
|
370
|
+
disallow: ["/admin", "/private"],
|
|
371
|
+
},
|
|
372
|
+
sitemap: "https://example.com/sitemap.xml",
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Add a rewrite in `next.config.ts`:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
{
|
|
380
|
+
source: "/robots.txt",
|
|
381
|
+
destination: "/api/robots.txt",
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Note:** For App Router, use the [native `robots.ts` file convention](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/robots) instead.
|
|
386
|
+
|
|
387
|
+
## Requirements
|
|
388
|
+
|
|
389
|
+
This package requires a **Node.js server runtime**. It works with:
|
|
390
|
+
- Vercel
|
|
391
|
+
- Netlify (with Next.js runtime)
|
|
392
|
+
- Railway, Render, Fly.io
|
|
393
|
+
- AWS (EC2, ECS, Lambda)
|
|
394
|
+
- Docker containers
|
|
395
|
+
- Any Node.js server
|
|
396
|
+
|
|
397
|
+
It does **not** work with static exports (`output: 'export'`) or static hosting platforms like Cloudflare Pages, Netlify (static mode), or GitHub Pages.
|
|
398
|
+
|
|
357
399
|
## Troubleshooting
|
|
358
400
|
|
|
359
401
|
### Dynamic routes not included in sitemap
|
package/dist/pages/index.cjs
CHANGED
|
@@ -100,6 +100,44 @@ ${allEntries}
|
|
|
100
100
|
</sitemapindex>`;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
// src/pages/robots.ts
|
|
104
|
+
function generateRobotsTxt(config) {
|
|
105
|
+
const lines = [];
|
|
106
|
+
const rules = Array.isArray(config.rules) ? config.rules : [config.rules];
|
|
107
|
+
for (const rule of rules) {
|
|
108
|
+
const userAgents = Array.isArray(rule.userAgent) ? rule.userAgent : [rule.userAgent];
|
|
109
|
+
for (const userAgent of userAgents) {
|
|
110
|
+
lines.push(`User-agent: ${userAgent}`);
|
|
111
|
+
}
|
|
112
|
+
if (rule.allow) {
|
|
113
|
+
const allows = Array.isArray(rule.allow) ? rule.allow : [rule.allow];
|
|
114
|
+
for (const allow of allows) {
|
|
115
|
+
lines.push(`Allow: ${allow}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (rule.disallow) {
|
|
119
|
+
const disallows = Array.isArray(rule.disallow) ? rule.disallow : [rule.disallow];
|
|
120
|
+
for (const disallow of disallows) {
|
|
121
|
+
lines.push(`Disallow: ${disallow}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (rule.crawlDelay !== void 0) {
|
|
125
|
+
lines.push(`Crawl-delay: ${rule.crawlDelay}`);
|
|
126
|
+
}
|
|
127
|
+
lines.push("");
|
|
128
|
+
}
|
|
129
|
+
if (config.sitemap) {
|
|
130
|
+
const sitemaps = Array.isArray(config.sitemap) ? config.sitemap : [config.sitemap];
|
|
131
|
+
for (const sitemap of sitemaps) {
|
|
132
|
+
lines.push(`Sitemap: ${sitemap}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (config.host) {
|
|
136
|
+
lines.push(`Host: ${config.host}`);
|
|
137
|
+
}
|
|
138
|
+
return lines.join("\n").trim() + "\n";
|
|
139
|
+
}
|
|
140
|
+
|
|
103
141
|
// src/pages/index.ts
|
|
104
142
|
function extractRoutes(pagesContext, localeSegment) {
|
|
105
143
|
const routes = [];
|
|
@@ -267,7 +305,16 @@ async function getSitemapStaticPaths(options) {
|
|
|
267
305
|
fallback: false
|
|
268
306
|
};
|
|
269
307
|
}
|
|
308
|
+
function createRobotsApiHandler(config) {
|
|
309
|
+
return function handler(_req, res) {
|
|
310
|
+
const robotsTxt = generateRobotsTxt(config);
|
|
311
|
+
res.setHeader("Content-Type", "text/plain");
|
|
312
|
+
res.status(200).send(robotsTxt);
|
|
313
|
+
};
|
|
314
|
+
}
|
|
270
315
|
|
|
316
|
+
exports.createRobotsApiHandler = createRobotsApiHandler;
|
|
271
317
|
exports.createSitemapApiHandler = createSitemapApiHandler;
|
|
272
318
|
exports.createSitemapIndexApiHandler = createSitemapIndexApiHandler;
|
|
319
|
+
exports.generateRobotsTxt = generateRobotsTxt;
|
|
273
320
|
exports.getSitemapStaticPaths = getSitemapStaticPaths;
|
package/dist/pages/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { NextApiRequest, NextApiResponse } from 'next';
|
|
1
|
+
import { MetadataRoute, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
export { MetadataRoute } from 'next';
|
|
2
3
|
|
|
3
4
|
type ChangeFrequency = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
4
5
|
interface SitemapConfig {
|
|
@@ -72,6 +73,12 @@ type PageModule = {
|
|
|
72
73
|
generateStaticParams?: () => Promise<Record<string, string>[]>;
|
|
73
74
|
};
|
|
74
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Generate robots.txt content from configuration
|
|
78
|
+
* Compatible with Next.js MetadataRoute.Robots
|
|
79
|
+
*/
|
|
80
|
+
declare function generateRobotsTxt(config: MetadataRoute.Robots): string;
|
|
81
|
+
|
|
75
82
|
interface CreateSitemapApiHandlerOptions extends SitemapConfig {
|
|
76
83
|
/**
|
|
77
84
|
* The require.context result for page discovery
|
|
@@ -110,5 +117,23 @@ declare function getSitemapStaticPaths(options: CreateSitemapApiHandlerOptions):
|
|
|
110
117
|
}[];
|
|
111
118
|
fallback: boolean;
|
|
112
119
|
}>;
|
|
120
|
+
/**
|
|
121
|
+
* Create API handler for robots.txt
|
|
122
|
+
* Use in: pages/api/robots.txt.ts or pages/robots.txt.ts (with rewrites)
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // pages/api/robots.txt.ts
|
|
126
|
+
* import { createRobotsApiHandler } from "@onruntime/next-sitemap/pages";
|
|
127
|
+
*
|
|
128
|
+
* export default createRobotsApiHandler({
|
|
129
|
+
* rules: {
|
|
130
|
+
* userAgent: "*",
|
|
131
|
+
* allow: "/",
|
|
132
|
+
* disallow: ["/admin", "/private"],
|
|
133
|
+
* },
|
|
134
|
+
* sitemap: "https://example.com/sitemap.xml",
|
|
135
|
+
* });
|
|
136
|
+
*/
|
|
137
|
+
declare function createRobotsApiHandler(config: MetadataRoute.Robots): (_req: NextApiRequest, res: NextApiResponse) => void;
|
|
113
138
|
|
|
114
|
-
export { type ChangeFrequency, type CreateSitemapApiHandlerOptions, type SitemapConfig, type SitemapEntry, createSitemapApiHandler, createSitemapIndexApiHandler, getSitemapStaticPaths };
|
|
139
|
+
export { type ChangeFrequency, type CreateSitemapApiHandlerOptions, type SitemapConfig, type SitemapEntry, createRobotsApiHandler, createSitemapApiHandler, createSitemapIndexApiHandler, generateRobotsTxt, getSitemapStaticPaths };
|
package/dist/pages/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { NextApiRequest, NextApiResponse } from 'next';
|
|
1
|
+
import { MetadataRoute, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
export { MetadataRoute } from 'next';
|
|
2
3
|
|
|
3
4
|
type ChangeFrequency = "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
|
|
4
5
|
interface SitemapConfig {
|
|
@@ -72,6 +73,12 @@ type PageModule = {
|
|
|
72
73
|
generateStaticParams?: () => Promise<Record<string, string>[]>;
|
|
73
74
|
};
|
|
74
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Generate robots.txt content from configuration
|
|
78
|
+
* Compatible with Next.js MetadataRoute.Robots
|
|
79
|
+
*/
|
|
80
|
+
declare function generateRobotsTxt(config: MetadataRoute.Robots): string;
|
|
81
|
+
|
|
75
82
|
interface CreateSitemapApiHandlerOptions extends SitemapConfig {
|
|
76
83
|
/**
|
|
77
84
|
* The require.context result for page discovery
|
|
@@ -110,5 +117,23 @@ declare function getSitemapStaticPaths(options: CreateSitemapApiHandlerOptions):
|
|
|
110
117
|
}[];
|
|
111
118
|
fallback: boolean;
|
|
112
119
|
}>;
|
|
120
|
+
/**
|
|
121
|
+
* Create API handler for robots.txt
|
|
122
|
+
* Use in: pages/api/robots.txt.ts or pages/robots.txt.ts (with rewrites)
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // pages/api/robots.txt.ts
|
|
126
|
+
* import { createRobotsApiHandler } from "@onruntime/next-sitemap/pages";
|
|
127
|
+
*
|
|
128
|
+
* export default createRobotsApiHandler({
|
|
129
|
+
* rules: {
|
|
130
|
+
* userAgent: "*",
|
|
131
|
+
* allow: "/",
|
|
132
|
+
* disallow: ["/admin", "/private"],
|
|
133
|
+
* },
|
|
134
|
+
* sitemap: "https://example.com/sitemap.xml",
|
|
135
|
+
* });
|
|
136
|
+
*/
|
|
137
|
+
declare function createRobotsApiHandler(config: MetadataRoute.Robots): (_req: NextApiRequest, res: NextApiResponse) => void;
|
|
113
138
|
|
|
114
|
-
export { type ChangeFrequency, type CreateSitemapApiHandlerOptions, type SitemapConfig, type SitemapEntry, createSitemapApiHandler, createSitemapIndexApiHandler, getSitemapStaticPaths };
|
|
139
|
+
export { type ChangeFrequency, type CreateSitemapApiHandlerOptions, type SitemapConfig, type SitemapEntry, createRobotsApiHandler, createSitemapApiHandler, createSitemapIndexApiHandler, generateRobotsTxt, getSitemapStaticPaths };
|
package/dist/pages/index.js
CHANGED
|
@@ -98,6 +98,44 @@ ${allEntries}
|
|
|
98
98
|
</sitemapindex>`;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
// src/pages/robots.ts
|
|
102
|
+
function generateRobotsTxt(config) {
|
|
103
|
+
const lines = [];
|
|
104
|
+
const rules = Array.isArray(config.rules) ? config.rules : [config.rules];
|
|
105
|
+
for (const rule of rules) {
|
|
106
|
+
const userAgents = Array.isArray(rule.userAgent) ? rule.userAgent : [rule.userAgent];
|
|
107
|
+
for (const userAgent of userAgents) {
|
|
108
|
+
lines.push(`User-agent: ${userAgent}`);
|
|
109
|
+
}
|
|
110
|
+
if (rule.allow) {
|
|
111
|
+
const allows = Array.isArray(rule.allow) ? rule.allow : [rule.allow];
|
|
112
|
+
for (const allow of allows) {
|
|
113
|
+
lines.push(`Allow: ${allow}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (rule.disallow) {
|
|
117
|
+
const disallows = Array.isArray(rule.disallow) ? rule.disallow : [rule.disallow];
|
|
118
|
+
for (const disallow of disallows) {
|
|
119
|
+
lines.push(`Disallow: ${disallow}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (rule.crawlDelay !== void 0) {
|
|
123
|
+
lines.push(`Crawl-delay: ${rule.crawlDelay}`);
|
|
124
|
+
}
|
|
125
|
+
lines.push("");
|
|
126
|
+
}
|
|
127
|
+
if (config.sitemap) {
|
|
128
|
+
const sitemaps = Array.isArray(config.sitemap) ? config.sitemap : [config.sitemap];
|
|
129
|
+
for (const sitemap of sitemaps) {
|
|
130
|
+
lines.push(`Sitemap: ${sitemap}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (config.host) {
|
|
134
|
+
lines.push(`Host: ${config.host}`);
|
|
135
|
+
}
|
|
136
|
+
return lines.join("\n").trim() + "\n";
|
|
137
|
+
}
|
|
138
|
+
|
|
101
139
|
// src/pages/index.ts
|
|
102
140
|
function extractRoutes(pagesContext, localeSegment) {
|
|
103
141
|
const routes = [];
|
|
@@ -265,5 +303,12 @@ async function getSitemapStaticPaths(options) {
|
|
|
265
303
|
fallback: false
|
|
266
304
|
};
|
|
267
305
|
}
|
|
306
|
+
function createRobotsApiHandler(config) {
|
|
307
|
+
return function handler(_req, res) {
|
|
308
|
+
const robotsTxt = generateRobotsTxt(config);
|
|
309
|
+
res.setHeader("Content-Type", "text/plain");
|
|
310
|
+
res.status(200).send(robotsTxt);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
268
313
|
|
|
269
|
-
export { createSitemapApiHandler, createSitemapIndexApiHandler, getSitemapStaticPaths };
|
|
314
|
+
export { createRobotsApiHandler, createSitemapApiHandler, createSitemapIndexApiHandler, generateRobotsTxt, getSitemapStaticPaths };
|
package/package.json
CHANGED