19

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
  • 851
  • 5
  • 20
  • 48

3 Answers3

9

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.

Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51
  • 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 Oct 09 '20 at 03:21
  • 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.. – Undefined Oct 09 '20 at 03:25
  • Missing [.env.local](https://github.com/mattcarlotta/with-static-export-express-app/blob/master/.env.local)? – Matt Carlotta Oct 09 '20 at 03:26
  • Absolutely you are right.. I had ```.env.local``` file already but missed adding these variables.. Thanks for your quick response.. – Undefined Oct 09 '20 at 03:31
  • 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.. – Undefined Oct 09 '20 at 03:32
  • Best place to start is their [documentation](https://nextjs.org/docs/getting-started) and [examples](https://github.com/vercel/next.js/tree/canary/examples) – Matt Carlotta Oct 09 '20 at 03:50
  • @MattCarlotta Can you provide a sample Nginx config? – R.M. Reza Mar 18 '21 at 13:46
3

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',
}
Surjeet Bhadauriya
  • 6,755
  • 3
  • 34
  • 52
  • 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.. – Undefined Aug 21 '20 at 08:20
  • @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. – Surjeet Bhadauriya Aug 21 '20 at 08:25
  • 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 Aug 21 '20 at 08:28
  • 1
    The best and easiest solution. – Nidhi Dadiya Apr 27 '22 at 12:34
3

If you have a NextJS site with nested paths folders/files, you need a local server configured with fallback logic. Consider a next export which generates:

/out
  /_next
  /docs
    /guide.html
  /index.html
  /docs.html

When you load the url http://localhost:3000/docs, your local server should serve /docs.html because /docs/index.html does not exist.

The only local server which correctly configured this by default was: https://www.npmjs.com/package/serve

npm install serve --save-dev

Then add a dev:static command to your package.json:

  "scripts": {
    "dev": "next dev",
    "dev:static": "serve ./out",
    "build": "next build && next export",
    "start": "next start"
  },

Then run the commands to view the static site locally:

npm run build
npm run dev:static
Kim T
  • 5,770
  • 1
  • 52
  • 79