Files
next.js/docs/01-app/02-guides/custom-server.mdx
151b415c9d docs: Fix custom server code snippets (#89400)
I noticed the snippets were slightly broken when copying them to an app.

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->

Co-authored-by: Joseph <[email protected]>
2026-02-02 19:12:59 +01:00

119 lines
5.7 KiB
Plaintext

---
title: How to set up a custom server in Next.js
nav_title: Custom Server
description: Start a Next.js app programmatically using a custom server.
---
{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
Next.js includes its own server with `next start` by default. If you have an existing backend, you can still use it with Next.js (this is not a custom server). A custom Next.js server allows you to programmatically start a server for custom patterns. The majority of the time, you will not need this approach. However, it's available if you need to eject.
> **Good to know**:
>
> - Before deciding to use a custom server, keep in mind that it should only be used when the integrated router of Next.js can't meet your app requirements. A custom server will remove important performance optimizations, like **[Automatic Static Optimization](/docs/pages/building-your-application/rendering/automatic-static-optimization).**
> - When using standalone output mode, it does not trace custom server files. This mode outputs a separate minimal `server.js` file, instead. These cannot be used together.
Take a look at the [following example](https://github.com/vercel/next.js/tree/canary/examples/custom-server) of a custom server:
```ts filename="server.ts" switcher
import { createServer } from 'http'
import next from 'next'
const port = parseInt(process.env.PORT || '3000', 10)
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
handle(req, res)
}).listen(port)
console.log(
`> Server listening at http://localhost:${port} as ${
dev ? 'development' : process.env.NODE_ENV
}`
)
})
```
```js filename="server.js" switcher
import { createServer } from 'http'
import next from 'next'
const port = parseInt(process.env.PORT || '3000', 10)
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
handle(req, res)
}).listen(port)
console.log(
`> Server listening at http://localhost:${port} as ${
dev ? 'development' : process.env.NODE_ENV
}`
)
})
```
> `server.js` does not run through the Next.js Compiler or bundling process. Make sure the syntax and source code this file requires are compatible with the current Node.js version you are using. [View an example](https://github.com/vercel/next.js/tree/canary/examples/custom-server).
To run the custom server, you'll need to update the `scripts` in `package.json` like so:
```json filename="package.json"
{
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
}
}
```
Alternatively, you can set up `nodemon` ([example](https://github.com/vercel/next.js/tree/canary/examples/custom-server)). The custom server uses the following import to connect the server with the Next.js application:
```js
import next from 'next'
const app = next({})
```
The above `next` import is a function that receives an object with the following options:
| Option | Type | Description |
| ------------ | ------------------ | ----------------------------------------------------------------------------------- |
| `conf` | `Object` | The same object you would use in `next.config.js`. Defaults to `{}` |
| `dev` | `Boolean` | (_Optional_) Whether or not to launch Next.js in dev mode. Defaults to `false` |
| `dir` | `String` | (_Optional_) Location of the Next.js project. Defaults to `'.'` |
| `quiet` | `Boolean` | (_Optional_) Hide error messages containing server information. Defaults to `false` |
| `hostname` | `String` | (_Optional_) The hostname the server is running behind |
| `port` | `Number` | (_Optional_) The port the server is running behind |
| `httpServer` | `node:http#Server` | (_Optional_) The HTTP Server that Next.js is running behind |
| `turbopack` | `Boolean` | (_Optional_) Enable Turbopack (enabled by default) |
| `webpack` | `Boolean` | (_Optional_) Enable webpack |
The returned `app` can then be used to let Next.js handle requests as required.
<PagesOnly>
## Disabling file-system routing
By default, `Next` will serve each file in the `pages` folder under a pathname matching the filename. If your project uses a custom server, this behavior may result in the same content being served from multiple paths, which can present problems with SEO and UX.
To disable this behavior and prevent routing based on files in `pages`, open `next.config.js` and disable the `useFileSystemPublicRoutes` config:
```js filename="next.config.js"
module.exports = {
useFileSystemPublicRoutes: false,
}
```
> Note that `useFileSystemPublicRoutes` disables filename routes from SSR; client-side routing may still access those paths. When using this option, you should guard against navigation to routes you do not want programmatically.
> You may also wish to configure the client-side router to disallow client-side redirects to filename routes; for that refer to [`router.beforePopState`](/docs/pages/api-reference/functions/use-router#routerbeforepopstate).
</PagesOnly>