Next.js 14 App Router Custom Server with Express
Submitted on Dec 31, 2023, 12:20 a.m.
Vercel / Next .js no longer publish an example custom webserver for Next.js 14 App router.
There is a discussion here https://github.com/vercel/next.js/discussions/49326 - and a few 'hidden' Medium posts, but none that show a clear Express / Next.js 14 App router configuration.
As with Next 13 and the Pages example that Vercel have published, if you create a custom server you will not be able to deploy to Vercel.
Below is the server which is a typescript file - server.ts
placed below a src directory (but at the same level and outside the app directory.
Note that Next.js 14 built via Webpack is still a CommonJS application, and so we cannot use Node.js ESM top-level await.
import dotenv from 'dotenv'import next from 'next'import nextBuild from 'next/dist/build'import path from 'path'
// This will depend on whether your server.ts file and general// app setup is located below a src folder or not.dotenv.config({ path: path.resolve(__dirname, '../.env'),})
import express from 'express'
const app = express()const PORT = process.env.PORT || 3000
const start = async (): Promise<void> => { if (process.env.NEXT_BUILD) { app.listen(PORT, async () => { console.log(`Next.js is now building...`) // @ts-expect-error await nextBuild(path.join(__dirname, '..')) process.exit() })
return }
const nextApp = next({ dev: process.env.NODE_ENV !== 'production', })
const nextHandler = nextApp.getRequestHandler()
app.use((req, res) => nextHandler(req, res))
nextApp.prepare().then(() => { console.log('Next.js started')
app.listen(PORT, async () => { console.log(`Next.js App URL: ${process.env.NEXT_SERVER_URL}`) }) })}
start()
Hope this helps...