Vilva Athiban P B JavaScript developer. React, Node, GraphQL. Trying to make the web a better place to browse.

Exploring zones in Next.js

2 min read 774

Exploring Zones in Next.js

Next.js is awesome, and it has become a favored tool for frontend developers. The evolution of Next.js has been marvelous — it has so many features that help us write production-ready apps quickly and easily.

The framework expects all the routes to be within the pages folder. However, in a real-world scenario, we will have many teams working on individual pages or components, and we can’t realistically expect them to commit to a monolith.

The solution to this problem is zones. As per the Next.js docs, a zone is a single deployment of a Next.js app.

Next.js allows you to have multiple zones for the deployment of individual Next.js apps, and all the zones can be accessed under a single URL. This allows different teams to build and deploy parts of the app individually, while on the user’s end, it appears as one complete application.

How do Next.js zones work?

Zones don’t have any specific APIs from Next.js; it’s based on HTTP proxies. You can implement multiple zones either with inbuilt support in Vercel or create your own HTTP proxy. However, Vercel tries to sell its own deployment by not providing examples for custom proxies, instead showing how simple it is in their platform.

Using Vercel

If you use Vercel, it’s pretty simple. They have inbuilt support for zones, and you just have to list the builds of your individual apps and the routes for serving them in vercel.json.

Next.js Zones Implementation Using Vercel

Using a custom proxy

In a custom proxy, we can create a proxy server, like an Nginx server. This server will redirect internally to the respective Next.js apps.

Next.js Zones Implementation Using an HTTP Proxy

There are two major things to consider when using zones:

  1. Next.js has provisions to add multiple pages inside each zone, but no two pages can have the same name across all zones. Thus, all the pages across all zones should have unique names.
  2. You run the risk of potential conflicts in static files.

In order to solve any conflicts among static files, we can leverage the assetPrefix. This will enable unique paths for all the static files based on the assetPrefix. Read more here.

module.exports = {
  assetPrefix: "about/",
}

Sample implementation using HTTP proxy

1. Create two Next.js apps

Create a new folder called nextjs-zones and use create-next-app to bootstrap two new Next.js projects: home and about.

Let’s create a page inside each project.

// home/pages/home.js
function Home() {
  return (
    <div>
      <h1>Home</h1>
    </div>
  );
}
export default Home;
// about/pages/about.js
function About() {
  return (
    <div>
      <h1>About</h1>
    </div>
  );
}
export default About;

2. Run both apps independently on different ports

Home → localhost:3000

About → localhost:3001

3. Create an Nginx reverse proxy and run it

# Sample nginx config

daemon off;
pid nginx.pid;

http {
    server {
        listen       8000;
        server_name  http://localhost:8000;
        proxy_buffering off;
        proxy_http_version 1.1;

        location / {
            proxy_pass    http://localhost:3000/home;
            proxy_redirect off;
        }
        location /about/ {
            proxy_pass    http://localhost:3001/about;
            proxy_redirect off;
        }
    }
}
events {
}

Now the Nginx server runs at localhost:8000 and directly points to the Home application. Likewise, localhost:8000/about points to the About application. Though Home and About run as different applications, both are now accessible through localhost:8000 now.

This is a very naive implementation to explain the concept. A more robust implementation would reverse-proxy the build files inside a Docker container.

Sample implementation using Vercel

1. Create two Next.js apps

Follow the same steps as above.

2. Create a vercel.json file

If you’re using Vercel as your deployment platform, it supports zones out of the box. Let’s create a vercel.json file with some data and we’ll be good to go.



// A sample vercel.json
{
  "version": 2,
  "build": {
    "env": {
      "BUILDING_FOR_NOW": "true"
    }
  },
  "builds": [
    { "src": "about/package.json", "use": "@now/next" },
    { "src": "home/package.json", "use": "@now/next" }
  ],
  "routes": [
    { "src": "/about(.*)", "dest": "about$1" },
    { "src": "(.*)", "dest": "home$1" }
  ]
}

Here we can combine different types of zones together — e.g., an SSG zone and a Next zone can work under the same URL. In the above example, we are using @now/next for both Home and About, and we define routes that help Vercel decide which build to load based on the URLs.

This approach has the potential to solve a lot of issues for larger teams using Next.js by decoupling the applications to a greater extent. This feature can be used even better with webpack module federation, and it could truly become the next big thing in micro-frontends.

If you have a better approach or ideology, please let me know in the comments.

LogRocket: Full visibility into production Next.js apps

Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your Next.js apps — .

Vilva Athiban P B JavaScript developer. React, Node, GraphQL. Trying to make the web a better place to browse.

Leave a Reply