Direct Answer: Next.js App Router Default Crawler Behavior
Next.js App Router provides a dedicated convention for generating robots.txt via `app/robots.ts` (or `app/robots.js`). Instead of hosting a static `public/robots.txt` file, creating an `app/robots.ts` file allows you to export a default function returning `MetadataRoute.Robots`. This unlocks dynamic runtime environment checks (e.g., blocking staging deployments with Disallow: / while allowing production) and dynamically populated multi-sitemap arrays, compiled automatically to standard text/plain at build or request time.
Configuring Dynamic MetadataRoute.Robots in Next.js App Router
Technical deep dive into Next.js App Router robots configuration quirks and indexing safety
Modern Next.js applications (Next.js 13.3+, Next.js 14, and Next.js 15+) replace legacy static public/robots.txt files with special Metadata Route Handlers (app/robots.ts or app/robots.js).
Why Use app/robots.ts Over public/robots.txt?
Static files in the public/ folder cannot react to environment variables or dynamic deployment URLs. In contrast, app/robots.ts gives you full programmatic control:
- Environment Branch Protection: Automatically disallow search engines on Vercel Preview or staging branches (
VERCEL_ENV !== 'production') while keeping production crawlable. - Dynamic Sitemaps: Automatically concatenate multi-language or multi-section sitemap URLs based on runtime configuration.
- Strict Type Safety: TypeScript validates that your rules, user agents, allow paths, and crawl delays match Next.js
MetadataRoute.Robotsspecifications.
Production Next.js app/robots.ts Code Structure
Below is the recommended production implementation for Next.js App Router:
// app/robots.ts (Next.js App Router)
import type { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
const isProduction = process.env.NEXT_PUBLIC_SITE_ENV === 'production';
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://yourdomain.com';
// Disallow all crawlers on Staging / Preview deployments
if (!isProduction) {
return {
rules: {
userAgent: '*',
disallow: '/',
},
};
}
// Production: Allow standard search engines + block AI model scrapers
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/', '/admin/', '/private/', '/_next/'],
},
{
userAgent: ['GPTBot', 'ClaudeBot', 'Google-Extended', 'CCBot', 'Bytespider'],
disallow: '/',
},
],
sitemap: `${baseUrl}/sitemap.xml`,
host: baseUrl,
};
}
// app/robots.ts (Next.js App Router)
import type { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
const isProduction = process.env.NEXT_PUBLIC_APP_ENV === 'production';
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://yourdomain.com';
if (!isProduction) {
return {
rules: {
userAgent: '*',
disallow: '/',
},
};
}
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/', '/admin/', '/private/', '/_next/'],
},
{
userAgent: ['GPTBot', 'ClaudeBot', 'Google-Extended', 'CCBot', 'Bytespider'],
disallow: '/',
},
],
sitemap: `${baseUrl}/sitemap.xml`,
host: baseUrl,
};
}How to Configure Next.js Robots Directives (Step-by-Step)
Four proven steps to safely deploy robots.txt rules in Next.js App Router
- 1
Create app/robots.ts in App Router
Add a new file at `src/app/robots.ts` or `app/robots.ts` in your Next.js project.
- 2
Import MetadataRoute Type Definition
Import `import type { MetadataRoute } from 'next';` for strict TypeScript autocomplete and schema validation.
- 3
Implement Dynamic Environment Logic
Return `disallow: '/'` if on preview or staging branches, and your full production crawler permissions when `NODE_ENV === 'production'`.
- 4
Remove Legacy public/robots.txt
Delete any existing `public/robots.txt` file to avoid build warnings and ensure Next.js serves the dynamic route handler.
Next.js Robots.txt FAQ
Troubleshooting crawler errors, file overrides, and CMS-specific directives
Does app/robots.ts override public/robots.txt in Next.js?
In Next.js App Router, if both `app/robots.ts` and `public/robots.txt` exist in your project, Next.js triggers a build warning and `public/robots.txt` takes static file serving precedence over the dynamic TypeScript route. You should always delete `public/robots.txt` when using `app/robots.ts`.
How do I handle environment-specific robots rules in Next.js (staging vs production)?
Inside `app/robots.ts`, inspect environment variables such as `process.env.VERCEL_ENV` or `process.env.NODE_ENV`. If the environment is 'preview' or 'staging', return `{ rules: { userAgent: '*', disallow: '/' } }` to prevent pre-production environments from being indexed in search engines.
How do I add dynamic multi-sitemap arrays in Next.js robots.ts?
The `sitemap` property in Next.js `MetadataRoute.Robots` supports either a single string or an array of strings: `sitemap: ['https://example.com/sitemap.xml', 'https://example.com/sitemap-blog.xml']`. Next.js automatically outputs individual `Sitemap:` lines for each entry in the compiled `/robots.txt`.
CMS & Framework Robots Directives
Switch presets to configure and validate robots.txt files for your specific tech stack
Generate and validate Shopify robots.txt.liquid directives. Fix default /checkout and /cart disallow rules, unblock collection filters, and manage AI scrapers safely.
Create and validate WordPress robots.txt files. Prevent Yoast and RankMath virtual file conflicts, protect /wp-admin/ while keeping admin-ajax.php accessible.
Validate and generate type-safe robots directives for Next.js App Router. Export MetadataRoute.Robots objects with dynamic sitemap arrays and AI crawler rules.