experimental.adapterPath
Next.js provides an experimental API that allows you to create custom adapters to hook into the build process. This is useful for deployment platforms or custom build integrations that need to modify the Next.js configuration or process the build output.
Configuration
To use an adapter, specify the path to your adapter module in experimental.adapterPath:
/** @type {import('next').NextConfig} */ const nextConfig = { experimental: { adapterPath: require.resolve('./my-adapter.js'), }, } module.exports = nextConfigCreating an Adapter
An adapter is a module that exports an object implementing the NextAdapter interface:
export interface NextAdapter { name: string modifyConfig?: ( config: NextConfigComplete, ctx: { phase: PHASE_TYPE } ) => Promise<NextConfigComplete> | NextConfigComplete onBuildComplete?: (ctx: { routes: { headers: Array<ManifestHeaderRoute> redirects: Array<ManifestRedirectRoute> rewrites: { beforeFiles: Array<ManifestRewriteRoute> afterFiles: Array<ManifestRewriteRoute> fallback: Array<ManifestRewriteRoute> } dynamicRoutes: ReadonlyArray<ManifestRoute> } outputs: AdapterOutputs projectDir: string repoRoot: string distDir: string config: NextConfigComplete nextVersion: string }) => Promise<void> | void }Basic Adapter Structure
Here's a minimal adapter example:
/** @type {import('next').NextAdapter} */ const adapter = { name: 'my-custom-adapter', async modifyConfig(config, { phase }) { // Modify the Next.js config based on the build phase if (phase === 'phase-production-build') { return { ...config, // Add your modifications } } return config }, async onBuildComplete({ routes, outputs, projectDir, repoRoot, distDir, config, nextVersion, }) { // Process the build output console.log('Build completed with', outputs.pages.length, 'pages') // Access different output types for (const page of outputs.pages) { console.log('Page:', page.pathname, 'at', page.filePath) } for (const apiRoute of outputs.pagesApi) { console.log('API Route:', apiRoute.pathname, 'at', apiRoute.filePath) } for (const appPage of outputs.appPages) { console.log('App Page:', appPage.pathname, 'at', appPage.filePath) } for (const prerender of outputs.prerenders) { console.log('Prerendered:', prerender.pathname) } }, } module.exports = adapterAPI Reference
modifyConfig(config, context)
Called for any CLI command that loads the next.config to allow modification of the configuration.
Parameters:
config: The complete Next.js configuration objectcontext.phase: The current build phase (see phases)
Returns: The modified configuration object (can be async)
onBuildComplete(context)
Called after the build process completes with detailed information about routes and outputs.
Parameters:
routes: Object containing route manifests for headers, redirects, rewrites, and dynamic routesroutes.headers: Array of header route objects withsource,sourceRegex,headers,has,missing, and optionalpriorityfieldsroutes.redirects: Array of redirect route objects withsource,sourceRegex,destination,statusCode,has,missing, and optionalpriorityfieldsroutes.rewrites: Object withbeforeFiles,afterFiles, andfallbackarrays, each containing rewrite route objects withsource,sourceRegex,destination,has, andmissingfieldsroutes.dynamicRoutes: Array of dynamic route objects withsource,sourceRegex,destination,has, andmissingfields
outputs: Detailed information about all build outputs organized by typeprojectDir: Absolute path to the Next.js project directoryrepoRoot: Absolute path to the detected repository rootdistDir: Absolute path to the build output directoryconfig: The final Next.js configuration (withmodifyConfigapplied)nextVersion: Version of Next.js being usedbuildId: Unique identifier for the current build
Output Types
The outputs object contains arrays of different output types:
Pages (outputs.pages)
React pages from the pages/ directory:
{ type: 'PAGES' id: string // Route identifier filePath: string // Path to the built file pathname: string // URL pathname sourcePage: string // Original source file path in pages/ directory runtime: 'nodejs' | 'edge' assets: Record<string, string> // Traced dependencies (key: relative path from repo root, value: absolute path) wasmAssets?: Record<string, string> // Bundled wasm files (key: name, value: absolute path) config: { maxDuration?: number preferredRegion?: string | string[] env?: Record<string, string> // Environment variables (edge runtime only) } }API Routes (outputs.pagesApi)
API routes from pages/api/:
{ type: 'PAGES_API' id: string filePath: string pathname: string sourcePage: string // Original relative source file path runtime: 'nodejs' | 'edge' assets: Record<string, string> wasmAssets?: Record<string, string> config: { maxDuration?: number preferredRegion?: string | string[] env?: Record<string, string> } }App Pages (outputs.appPages)
React pages from the app/ directory with page.{js,ts,jsx,tsx}:
{ type: 'APP_PAGE' id: string filePath: string pathname: string // Includes .rsc suffix for RSC routes sourcePage: string // Original relative source file path runtime: 'nodejs' | 'edge' assets: Record<string, string> wasmAssets?: Record<string, string> config: { maxDuration?: number preferredRegion?: string | string[] env?: Record<string, string> } }App Routes (outputs.appRoutes)
API and metadata routes from app/ with route.{js,ts,jsx,tsx}:
{ type: 'APP_ROUTE' id: string filePath: string pathname: string sourcePage: string runtime: 'nodejs' | 'edge' assets: Record<string, string> wasmAssets?: Record<string, string> config: { maxDuration?: number preferredRegion?: string | string[] env?: Record<string, string> } }Prerenders (outputs.prerenders)
ISR-enabled routes and static prerenders:
{ type: 'PRERENDER' id: string pathname: string parentOutputId: string // ID of the source page/route groupId: number // Revalidation group identifier (prerenders with same groupId revalidate together) pprChain?: { headers: Record<string, string> // PPR chain headers (e.g., 'x-nextjs-resume': '1') } parentFallbackMode?: 'blocking' | false | null // Fallback mode from getStaticPaths fallback?: { filePath: string initialStatus?: number initialHeaders?: Record<string, string | string[]> initialExpiration?: number initialRevalidate?: number postponedState?: string // PPR postponed state } config: { allowQuery?: string[] // Allowed query parameters allowHeader?: string[] // Allowed headers for ISR bypassFor?: RouteHas[] // Cache bypass conditions renderingMode?: RenderingMode bypassToken?: string } }Static Files (outputs.staticFiles)
Static assets and auto-statically optimized pages:
{ type: 'STATIC_FILE' id: string filePath: string pathname: string }Middleware (outputs.middleware)
Middleware function (if present):
{ type: 'MIDDLEWARE' id: string filePath: string pathname: string // Always '/_middleware' sourcePage: string // Always 'middleware' runtime: 'nodejs' | 'edge' assets: Record<string, string> wasmAssets?: Record<string, string> config: { maxDuration?: number preferredRegion?: string | string[] env?: Record<string, string> matchers?: Array<{ source: string sourceRegex: string has: RouteHas[] | undefined missing: RouteHas[] | undefined }> } }Routes Information
The routes object in onBuildComplete provides complete routing information with processed patterns ready for deployment:
Headers
Each header route includes:
source: Original route pattern (e.g.,/about)sourceRegex: Compiled regex for matching requestsheaders: Key-value pairs of headers to applyhas: Optional conditions that must be metmissing: Optional conditions that must not be metpriority: Optional flag for internal routes
Redirects
Each redirect route includes:
source: Original route patternsourceRegex: Compiled regex for matchingdestination: Target URL (can include captured groups)statusCode: HTTP status code (301, 302, 307, 308)has: Optional positive conditionsmissing: Optional negative conditionspriority: Optional flag for internal routes
Rewrites
Rewrites are categorized into three phases:
beforeFiles: Checked before filesystem (including pages and public files)afterFiles: Checked after pages/public files but before dynamic routesfallback: Checked after all other routes
Each rewrite includes source, sourceRegex, destination, has, and missing.
Dynamic Routes
Generated from dynamic route segments (e.g., [slug], [...path]). Each includes:
source: Route patternsourceRegex: Compiled regex with named capture groupsdestination: Internal destination with parameter substitutionhas: Optional positive conditionsmissing: Optional negative conditions
Use Cases
Common use cases for adapters include:
- Deployment Platform Integration: Automatically configure build outputs for specific hosting platforms
- Asset Processing: Transform or optimize build outputs
- Monitoring Integration: Collect build metrics and route information
- Custom Bundling: Package outputs in platform-specific formats
- Build Validation: Ensure outputs meet specific requirements
- Route Generation: Use processed route information to generate platform-specific routing configs
Was this helpful?