mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
Adapters implementing `modifyConfig` may need to know the absolute project directory to perform path resolution or apply directory-specific configuration logic. Without this value, adapters had no reliable way to determine where the application lives on disk. onBuildComplete already received the directory as a parameter.
126 lines
3.0 KiB
Plaintext
126 lines
3.0 KiB
Plaintext
---
|
|
title: Creating an Adapter
|
|
description: Create an adapter module that implements the `NextAdapter` interface.
|
|
---
|
|
|
|
An adapter is a module that exports an object implementing the `NextAdapter` interface.
|
|
|
|
The interface can be imported from the `next` package:
|
|
|
|
```typescript
|
|
import type { NextAdapter } from 'next'
|
|
```
|
|
|
|
The interface is defined as follows:
|
|
|
|
```typescript
|
|
type Route = {
|
|
source?: string
|
|
sourceRegex: string
|
|
destination?: string
|
|
headers?: Record<string, string>
|
|
has?: RouteHas[]
|
|
missing?: RouteHas[]
|
|
status?: number
|
|
priority?: boolean
|
|
}
|
|
|
|
export interface AdapterOutputs {
|
|
pages: Array<AdapterOutput['PAGES']>
|
|
middleware?: AdapterOutput['MIDDLEWARE']
|
|
appPages: Array<AdapterOutput['APP_PAGE']>
|
|
pagesApi: Array<AdapterOutput['PAGES_API']>
|
|
appRoutes: Array<AdapterOutput['APP_ROUTE']>
|
|
prerenders: Array<AdapterOutput['PRERENDER']>
|
|
staticFiles: Array<AdapterOutput['STATIC_FILE']>
|
|
}
|
|
|
|
export interface NextAdapter {
|
|
name: string
|
|
modifyConfig?: (
|
|
config: NextConfigComplete,
|
|
ctx: {
|
|
phase: PHASE_TYPE
|
|
nextVersion: string
|
|
projectDir: string
|
|
}
|
|
) => Promise<NextConfigComplete> | NextConfigComplete
|
|
onBuildComplete?: (ctx: {
|
|
routing: {
|
|
beforeMiddleware: Array<Route>
|
|
beforeFiles: Array<Route>
|
|
afterFiles: Array<Route>
|
|
dynamicRoutes: Array<Route>
|
|
onMatch: Array<Route>
|
|
fallback: Array<Route>
|
|
shouldNormalizeNextData: boolean
|
|
rsc: RoutesManifest['rsc']
|
|
}
|
|
outputs: AdapterOutputs
|
|
projectDir: string
|
|
repoRoot: string
|
|
distDir: string
|
|
config: NextConfigComplete
|
|
nextVersion: string
|
|
buildId: string
|
|
}) => Promise<void> | void
|
|
}
|
|
```
|
|
|
|
## Basic Adapter Structure
|
|
|
|
Here's a minimal adapter example:
|
|
|
|
```js filename="my-adapter.js"
|
|
/** @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({
|
|
routing,
|
|
outputs,
|
|
projectDir,
|
|
repoRoot,
|
|
distDir,
|
|
config,
|
|
nextVersion,
|
|
buildId,
|
|
}) {
|
|
// Process the build output
|
|
console.log('Build completed with', outputs.pages.length, 'pages')
|
|
console.log('Build ID:', buildId)
|
|
console.log('Dynamic routes:', routing.dynamicRoutes.length)
|
|
|
|
// Access emitted output entries
|
|
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 = adapter
|
|
```
|