How to run Next Js application build (out) directory?

15,339

Solution 1

The official Next static export example uses serve, to "serve" the out directory. Since the out directory is just a bunch of static files, you need some sort of connection layer to the outside world/internal network. You could use something like nginx to the serve these assets (which eliminates the need of having to run two web servers). But, if you're looking for an easy way to run a local staging build, then you'll need to use some sort of web server: express, http-server or serve to name a few.

...and can share the working build to anyone in team.

If you're remote and connecting to a WAN, then anyone from your team can visit the staging build (eg: http://wanlocalip:3000 -- you can use address to print out a console message). If you're not connecting to a WAN and if you don't have your own server, then you'll have to create a remote staging environment using a 3rd party service like vercel, AWS, or Digital Ocean to name a few.


With that out of the way, let's take the official with-static-export example and set up a custom express server.

First, we'll add a few dependencies: yarn add chalk dotenv express

Adjust the package.json file scripts to be:

  "scripts": {
    "dev": "next",
    "export": "next build && next export",
    "start": "NODE_ENV=production node ./server.js"
  },

Then we'll create a server.js file in the root directory:

server.js

const dotenv = require("dotenv");
// import ENVs from ".env.local" and append to process
dotenv.config({ path: ".env.local" }); 
const express = require("express");
const address = require("address");
const chalk = require("chalk");

// create express web server instance
const app = express();
// pull out ENVs from process
const { LOCALHOST, PORT } = process.env;
// get the Local IP address
const LOCALIP = address.ip();

// tell express to serve up production assets from the out directory
app.use(express.static("out"));

// tell express to listen for incoming connections on the specified PORT
app.listen(PORT, (err) => {
  if (!err) {
    // log the LOCALHOST and LOCALIP addresses where the app is running
    console.log(
      `\n${chalk.rgb(7, 54, 66).bgRgb(38, 139, 210)(" I ")} ${chalk.blue(
        "Application is running at"
      )} ${chalk.rgb(235, 220, 52).bold(LOCALHOST)} ${chalk.blue(
        "or"
      )} ${chalk.rgb(235, 220, 52).bold(`http://${LOCALIP}:${PORT}`)}\n`
    );
  } else {
    console.err(`\nUnable to start server: ${err}`);
  }
});

Optionally we can adjust the next.config.js to display a compilation message in development:

next.config.js

const { DefinePlugin } = require("webpack");
const FriendlyErrorsWebpackPlugin = require("friendly-errors-webpack-plugin");
const address = require("address");

const { LOCALHOST, NODE_ENV, PORT } = process.env;
const LOCALIP = address.ip();

const plugins = (isServer) => {
  const plugins = [];

  if (!isServer) {
    plugins.push(
      /* OPTIONAL -- append ENVS to client-side process */
      new DefinePlugin({
        "process.env": {
          LOCALHOST: JSON.stringify(LOCALHOST),
          NODE_ENV: JSON.stringify(NODE_ENV),
        },
      })
    );
  } else {
    plugins.push(
     /* add console compilation messages */
      NODE_ENV === "development" &&
        new FriendlyErrorsWebpackPlugin({
          compilationSuccessInfo: {
            messages: [
              `Local development build: \x1b[1m${LOCALHOST}\x1b[0m`,
              LOCALIP &&
                `Remote development build: \x1b[1mhttp://${LOCALIP}:${PORT}\x1b[0m`,
            ].filter(Boolean),
            notes: [
              "Note that the development build is not optimized.",
              "To create a production build, use \x1b[1m\x1b[32myarn export\x1b[0m.\n",
            ],
          },
          clearConsole: false,
        })
    );
  }

  return plugins.filter(Boolean);
};

module.exports = {
  webpack(config, { isServer }) {
    /* adds custom plugins to client and/or server */
    config.plugins.push(...plugins(isServer));

    /* return new config to next */
    return config;
  },
};

Now that we have everything set up, we can run yarn export to build and export the project to the out directory, then we can run a local staging environment by running yarn start. Visit one of the addresses printed in the console.

Local

WAN (only accessible to those connected to a LAN connection within the WAN)


Click here to see a working repo example of the above.

If you're still having trouble with your project, then please share a repository; otherwise, it's going to be very difficult to help you troubleshoot.

Solution 2

Run this command: npm run build && npm run export

It will create an out directory.

Then

To run the out/build/dist directory you can either install the web server for chrome addon in your chrome browser or install http-server. Here I am covering web server addon.

Link of web server for chrome: https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en

Launch the app and then choose your out/build/dist folder and then it will provide you a link, just navigate to the given link.

If you want to change out directory name then see below

next.js creates the .next directory instead of build.

To create custom directory say build, you need to set config in the next.config.js

next.config.js

module.exports = {
  distDir: 'build',
}
Share:
15,339
Undefined
Author by

Undefined

Updated on June 07, 2022

Comments

  • Undefined
    Undefined almost 2 years

    I have done development of Next Js application and as of now I have done auto deployment using vercel

    Things are fine as of now.. But here came the requirement that I need to build the Next Js application and share the build folder with the team for deployment in server.

    The commands I have followed,

    npm run build & npm run export

    And the above one creates the out directory.. So how to run this out directory in my local machine to check whether the build folder is working as expected before sharing with the team?

    Folder structure of out directory:

     -> out
    
          -> _next
                 -> static
                 -> xxxxxxxxxxxxx (some random name)
          -> static
          -> home.png
          -> location.png
    

    So anyone could kindly please help me how can I run this generated build folder (out) to check whether the developed Next Js application works fine in my local machine after which I can share the same build folder to the team?

    To be specific I would like to know how exactly I can build the next js application in my local and then to test that built folder in my local that will run the application and can share the working build to anyone in team.

    Raised issue here https://github.com/vercel/next.js/discussions/16439 but that didn't help in anyway..

  • Undefined
    Undefined over 3 years
    There is nothing like out/build/dist created as I have already shared the folder structure above, you could see the sub folders of out dirctory.. I don't want to change the directory name but I just want to run the build folder (out directory) in my local machine.. Normal in angular application ng build will generate index.html under build folder and its possible to run the app but here in Next Js, I couldn't get how to run the build folder bcoz no index.html file is created here..
  • Surjeet Bhadauriya
    Surjeet Bhadauriya over 3 years
    @Undefined You already mentioned the folder structure of out directory that means it is creating but no index.html file is created as I understand. Try running your command like this npm run build && npm run export. Two & sign in between. Not sure this will solve the issue. But give a try once.
  • Undefined
    Undefined over 3 years
    It is same like if we run the command one by one npm run build then npm run export in the terminal or like npm run build && npm run export .. Both are same but that doesn't solve the issue..
  • Undefined
    Undefined over 3 years
    In your solution, in this line const { LOCALHOST, NODE_ENV, PORT } = process.env; I am getting LOCALHOST AND PORT as undefined in my application.. But if I clone and run your application then it is working.. So could you help me what would be wrong in my app?
  • Undefined
    Undefined over 3 years
    I am getting NEXTAUTH_URL from process.env and if I assign that instead of LOCALHOST then I am getting http://localhost:3000/ but if I run this url in browser then it doesn't work..
  • Matt Carlotta
    Matt Carlotta over 3 years
    Missing .env.local?
  • Undefined
    Undefined over 3 years
    Absolutely you are right.. I had .env.local file already but missed adding these variables.. Thanks for your quick response..
  • Undefined
    Undefined over 3 years
    If possible could you please share me some worth Next Js tutorial where I can learn things effectively.. I feel I am working in Next Js without knowing how to use it in right manner..
  • Matt Carlotta
    Matt Carlotta over 3 years
    Best place to start is their documentation and examples
  • R.M. Reza
    R.M. Reza about 3 years
    @MattCarlotta Can you provide a sample Nginx config?
  • Nidhi Dadiya
    Nidhi Dadiya about 2 years
    The best and easiest solution.