Search code examples
buildnext.js

nextjs custom serve directory in production


The problem: When I run next build on my production server, the page is served unstyled while building. What I want to do:

  1. build the app to build directory
  2. move build to build-public
  3. serve the app from build-public.

I don't want to setup a custom server for that simple task.

My package.json scripts section:

"scripts": {
    "dev": "next dev -p 3002",
    "build": "next build",
    "start": "next start -p 3002"
  },

My next.config.js:

module.exports = {
  basePath: '',
  distDir: 'build', // dir to build
  dir: 'build-public', // serve from build-public. 'Dir' option is not working.
}

Solution

  • tl/dr: see paragraph 3.

    1. replace next.config.js between build and serve Next.js uses distDir config option as the server directory, each time it launches a script. So, if I build my app with distDir set to build, then I get my bundle inside build directory. Next I change distDir to build-public, and run next start, so my project is served from build-public`.

    next.config.js

    module.exports = {
    ...
      distDir: 'build' // build to 'build' directory. Then change distDir to 'build-public', so it will serve from 'build-public'.
    ...
    }
    
    1. serve from nested directory I can run next serve ./build-public, and Nextjs will search for the app build inside ./build-public/build. So, after next build I need to move build folder to build-public/build and run next serve ./build-public.

    package.json

    ...
    "scripts": {
        "build": "next build",
        "start": "next start ./nested-dir -p 3011"
      },
    ...
    
    1. export a function in next.config.js. See more advanced example here: nextjs-examples

    next.config.js

    const {
      PHASE_PRODUCTION_BUILD,
      PHASE_PRODUCTION_SERVER,
    } = require("next/constants");
    
    module.exports = (phase) => {
      let distDir = "";
      if (phase == PHASE_PRODUCTION_BUILD) {
        distDir = "build";
      } else if (phase == PHASE_PRODUCTION_SERVER) {
        distDir = "build-public";
      }
    
      return {
        ... 
        distDir,
        ....
      }
    }