Status: Stable

The Now Next.js Builder takes a Next.js application, defined by a package.json entrypoint and pages directory, and converts those pages into a series of individual lambdas.

It features built-in caching of node_modules and all compiler artifacts for very fast deployments.

When to Use It

@now/next is the ideal way to ship a fast, production-ready Next.js application that scales automatically.

For more information on why you should use Next.js for your project, see the Next.js website.

How to Use It

The first step is to set up a Next.js project. If you have not yet done so; the best place to get started is the Next.js documentation.

To get started, make sure you have installed the Next.js dependencies with the following command:

yarn add next react react-dom
Note: The serverless option is only supported in Next.js version 8 and above.

Then, in your project directory, create a pages directory with some example pages, for example; the home index page, pages/index.js:

export default () => <div>Hello world!</div>

Then define a build step in a now.json configuration file:

{
  "version": 2,
  "builds": [{ "src": "package.json", "use": "@now/next" }]
}

Upon deployment, you will get a URL like the following: https://nextjs-8fnzfb1ci.now.sh

Also, the source code of the deployment can be checked by appending /_src e.g. https://nextjs-8fnzfb1ci.now.sh/_src.

For a more in-depth guide on setting up and deploying Next.js with caching headers, see our guide:

If you are looking to set up custom routes for your Next.js app, see the following guide:

Technical Details

Entrypoint

The entrypoint of this builder is a package.json with Next.js 8 or newer defined in dependencies.

This configuration, shown above, tells Next.js to build each page in the pages directory as a lambda function.

For more information on this, see the Next.js documentation.

Dependencies installation

The installation algorithm of dependencies works as follows:

  • If a package-lock.json is present, npm install is used
  • Otherwise, yarn is used.

Private npm modules

To install private npm modules, define NPM_TOKEN as a build environment variable in now.json.

Alternatively, define NPM_RC as a build environment variable with the contents of ~/.npmrc.

Exposing Configuration

To support configuration, Next.js inlines the provided values into the JavaScript bundle at build. This circumvents the performance concerns with runtime configuration along with the subtle issues associated with sharing configuration with the client.

You can add the env key to the next.config.js file:

module.exports = {
  env: {
    customKey: process.env.customKey,
    mySecret: process.env.mySecret
  }
}

An example next.config.js file.

Then, expose the build env in your now.json:

{
  ...
  "build": {
    "env": {
      "customKey": "value",
      "mySecret": "@my-secret-name"
    }
  }
}

An example now.json file specifying a build environment variable.

This will allow you to use process.env.customKey and process.env.mySecret in your code, for example:

function Index() {
  return (
    <div>
      <h1>The value of customKey is: {process.env.customKey}</h1>
      <h2>Your secret is: {process.env.mySecret}</h2>
    </div>
  )
}

export default Index

An example index.js file that references environment variables.

Which will be replaced with:

function Index() {
  return (
    <div>
      <h1>The value of customKey is: {'value'}</h1>
      <h2>Your secret is: {'secret-value'}</h2>
    </div>
  )
}

export default Index

An example index.js file that shows the value of the referenced environment variables.

Note: For local development with now dev, you should add your environment variables to a .env.build file.

Build Step

You can run build tasks by creating a now-build script within a package.json file. If no now-build script is defined, then next build is assumed. If now-build is defined, it will replace next build.

An example package.json with a now-build script:
{
  "scripts": {
    "now-build": "node build.js && next build"
  }
}
An example build script, named build.js:
const fs = require('fs');
const path = require('path');
const filename = path.join('pages', 'time.js');
const contents = `module.exports = "${new Date().toISOString()}"`;
fs.writeFile(filename, contents, (err) => {
  if (err) throw err
  console.log('time.js file created successfully!')
});
To tie it all together, add a now.json file:
{
  "version": 2,
  "builds": [
    { "src": "package.json", "use": "@now/next" }
  ]
}

The resulting Lambda contains the build time: https://nextjs-build-pqo9ri0y2.now.sh/

Node.js version

The default Node.js version used is 8.10.x.

The version can be changed to 10.x by defining engines in package.json.

Custom Server

This builder separates your pages into individual serverless endpoints, so you cannot use a custom server.

Using a custom server would require that all pages be routed through that custom server and the application would lose out on many of the benefits of serverless Next.js. You can still achieve most of the logic that you have in a custom server by using getInitialProps() and using routes.