Пользовательский сервер
По умолчанию Next.js включает собственный сервер с командой next start
. Если у вас есть существующий бэкенд, вы всё равно можете использовать его с Next.js (это не считается пользовательским сервером). Пользовательский сервер Next.js позволяет запускать сервер полностью программно для реализации пользовательских шаблонов сервера. В большинстве случаев это не потребуется, но возможность доступна для полной кастомизации.
Важно знать:
- Прежде чем решить использовать пользовательский сервер, учтите, что он нужен только когда встроенный роутер Next.js не удовлетворяет требованиям вашего приложения. Пользовательский сервер отключает важные оптимизации производительности, такие как бессерверные функции и Автоматическая статическая оптимизация.
- Пользовательский сервер не может быть развёрнут на Vercel.
Рассмотрим следующий пример пользовательского сервера:
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// при использовании middleware `hostname` и `port` должны быть указаны ниже
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer(async (req, res) => {
try {
// Обязательно передавайте `true` вторым аргументом в `url.parse`.
// Это указывает на необходимость разбора query-части URL.
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') {
await app.render(req, res, '/a', query)
} else if (pathname === '/b') {
await app.render(req, res, '/b', query)
} else {
await handle(req, res, parsedUrl)
}
} catch (err) {
console.error('Ошибка при обработке', req.url, err)
res.statusCode = 500
res.end('внутренняя ошибка сервера')
}
})
.once('error', (err) => {
console.error(err)
process.exit(1)
})
.listen(port, () => {
console.log(`> Готово на http://${hostname}:${port}`)
})
})
Файл
server.js
не проходит обработку через babel или webpack. Убедитесь, что синтаксис и используемые модули совместимы с текущей версией Node.js.
Для запуска пользовательского сервера обновите scripts
в package.json
следующим образом:
{
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
}
}
Пользовательский сервер использует следующий импорт для подключения к приложению Next.js:
const next = require('next')
const app = next({})
Импортируемая функция next
принимает объект со следующими опциями:
Опция | Тип | Описание |
---|---|---|
conf | Object | Тот же объект, что используется в next.config.js. По умолчанию {} |
customServer | Boolean | (Опционально) Установите false, если сервер создан Next.js |
dev | Boolean | (Опционально) Запускать ли Next.js в режиме разработки. По умолчанию false |
dir | String | (Опционально) Путь к проекту Next.js. По умолчанию '.' |
quiet | Boolean | (Опционально) Скрывать сообщения об ошибках с информацией о сервере. По умолчанию false |
hostname | String | (Опционально) Имя хоста, на котором работает сервер |
port | Number | (Опционально) Порт, на котором работает сервер |
httpServer | node:http#Server | (Опционально) HTTP-сервер, на котором работает Next.js |
Возвращаемый объект app
может использоваться для обработки запросов в Next.js по необходимости.
Отключение файлового роутинга
По умолчанию Next.js обслуживает каждый файл из папки pages
по пути, соответствующему имени файла. Если проект использует пользовательский сервер, это может привести к дублированию контента по разным путям, что создаёт проблемы для SEO и UX.
Чтобы отключить это поведение и предотвратить роутинг на основе файлов в pages
, откройте next.config.js
и отключите параметр useFileSystemPublicRoutes
:
module.exports = {
useFileSystemPublicRoutes: false,
}
Примечание:
useFileSystemPublicRoutes
отключает файловый роутинг только для SSR; клиентский роутинг всё ещё может обращаться к этим путям. При использовании этой опции следует программно ограничивать навигацию к нежелательным маршрутам.
Вы также можете настроить клиентский роутер для запрета клиентских перенаправлений к файловым маршрутам; для этого см.
router.beforePopState
.