NextJS Examples | Express

stackchief /

NextJS Express example including sample express app with NextJS, updating package.json for Express, and how nextApp.prepare works

NextJS Examples | Starter

NextJS Examples | Layout

NextJS Examples | Express

NextJS Examples | MongoDB

In this post, you will see how to configure the NextJS starter project with an Express app.

At the root of your NextJS project, create a server.js file. This will be the entry point for your app.

Following is an example Express configuration defined in the server.js file...

const express     = require('express')
const next        = require('next')
const bodyParser  = require('body-parser')
const posts       = require('./api/post')

//next.js configuration
const dev = process.env.NODE_DEV !== 'production'
const nextApp = next({ dev })
const handle = nextApp.getRequestHandler()

nextApp.prepare().then(() => {
  const app = express()
  app.use(bodyParser.urlencoded({ extended: true }))
  app.use('/posts', posts)

  //catch-all for nextJS /pages
  app.get('*', (req, res) => {
    return handle(req, res)
  app.listen(process.env.PORT, err => {
    if (err) throw err
    console.log('listening on port ' + process.env.port)

Notice how we first define a NextJS instance...

const nextApp = next({ dev })

We pass in a single option for dev which specifies to run NextJS in development mode.

We then call prepare() on our instance. This method "prepares" the NextJS server with configuration options for dev environment, directory, configuration etc.

In this example, all we've passed is the dev flag which tells the NextJS server to run in development mode if process.env.NODE_DEV !== 'production'.

Notice how we create our app after nextApp.prepare() resolves. From here, we can set up our Express server for different API routes defined outside of Next.

Notice how we declare a "catch all" route...

app.get('*', (req, res) => {
  return handle(req, res)

Express forwards request to Next via the request handler..

const handle = nextApp.getRequestHandler()

By calling handle(req, res), we forward any request not defined through Express to NextJS.

From here, the routes defined in pages/ are applied and Next "takes over" the request if not explicitly defined somewhere else by Express.

You can even "forward" requests to the NextJS routing system directly inside an Express route...

app.get('/post', (req, res) => {
  return nextApp.render(req, res, '/post')

Using render() will "forward" the request to a pages/post.js file.

Updating package.json

You must update the run scripts to point to the new server.js file...

"scripts": {
  "dev": "node server.js",
  "test": "jest",
  "build": "next build",
  "start": "NODE_ENV=production node server.js -p $PORT"

Notice how both the devand start script have been updated to point to our server.js file.

This allows us to deploy the application as an Express app using NextJS. If we don't update these scripts then NextJS will run using the default next start script.

Your thoughts?