Many projects are migrating from React to Next.js in 2023. So now's the right time to understand an important step in creating a Next.js application: deployment.

Deploying a Next.js application is an essential step in the lifecycle of your web product. And since various deployment strategies exist, picking the right one can be challenging.

This article will discuss different deployment strategies and practices for Next.js applications. We will explore each strategy's strengths, including static hosting, serverless functions, containerisation, and traditional server deployment.

We will also be touching on essential practices to optimise the deployment process and enhance the performance and reliability of your Next.js application.

Here's what we'll cover in this tutorial:

This article will provide comprehensive information that a beginner or an intermediate developer can use in deploying a smooth Next.js application.

Why is Deployment Important in the Development Lifecycle?

Deploying a project is more important than starting it. An application should solve problems for its users – but how can your users solve their problems with your app if you don't deploy it (making it available to the world)? The deployment process can make all your hard work fail if you miss a step.

The development process involves:

  • Putting your application on a hosting platform.
  • Configuring it.
  • Ensuring it runs smoothly for users across the globe.

Here are a few reasons why deployment is essential:

  • User Accessibility: The usability of a project is an important criterion. Deployment is the final step, without which your users can't interact with your app. Users should be able to access your project and use its features smoothly.
  • Real Users Test: Deploying your project is the only way to check if it solves the desired problem. It allows you to test and resolve bugs from real users and data and fix the application to work as intended.
  • Scalability and Reliability: Deploying your application allows your product to scale, handle more users, and increase traffic. Scalability and reliability are reasons you must use the appropriate deployment process, as it could jeopardize your effort if your product can't handle a spike in traffic.
  • Continuous Integration and Deployment (CI/CD): The deployment process implements a seamless workflow. With CI/CD practices, your codebase is always tested, validated, and deployed to the production environment. It also makes it easier to add features and avoid errors.

Deployment Strategies for Next.js Projects

Here is an overview of various deployment options for Next.js product workflows and requirements.

Option #1: Static Hosting

https://www.cosmicjs.com/blog/static-site-generators-explained-in-5-minutes
Diagram illustrating static hosting

A simple static website with little or no server-side rendering can be hosted on fixed hosting platforms like Vercel, Netlify, Amazon Simple Storage Service (AWS S3), GitHub Pages, or Surge.

Next.js generates static HTML files during the build process, and you can host it in one of the above platforms.

Benefits of Static Hosting for Next.js Apps

  • Improved Performance: Next.js apps generate pre-rendered HTML files during the building process, and it supports static site generation (SSG). If you host statically, the pre-rendered file can be cached on a global content delivery network (CDN), improving performance by loading fast.
  • Scalability: A static hosted application with a CDN will allow for the global distribution of files, thereby improving scalability and decreasing the load on the origin server. The CDN will ensure fast load times even during traffic spikes for users worldwide.
  • Security: Static hosting has little or no server-side processing, which reduces the attack surface. Also, static files are less vulnerable to common web application attacks.
  • Reduced Server Load: The origin server workload is reduced because Next.js has pre-rendered HTML files.
  • Caching Benefits: Since the static files are cached on the CDN, this will reduce the number of requests made to the origin server.
  • Cost-Effectiveness: Static hosting doesn't need database management or server-side processing. It will be cheaper for smaller applications and websites with low traffic.

Use Cases of Static Hosting for Next.js Apps

Static hosting is excellent for Next.js Apps with little rendering and maintenance.
Here are some use cases to consider:

  1. Landing pages: This is a simple website used for marketing campaigns or product launches. A Next.js landing page should be hosted statically to ensure smooth high-traffic handling and fast loading time.
  2. Content and Portfolio sites: Websites with multiple static contents like blogs, documentation sites, and knowledge-base sites enjoy improved performance and reduced load time when they use static hosting.
  3. Prototypes and Demos: Next.js applications can be used by developers for internal demos and prototyping with clients as they can easily be deployed.
  4. Single-page Applications (SPAs): SPAs usually contain dynamic contents, but the static part can be pre-rendered and hosted statically to improve loading time.

Examples of Static Hosting Platforms for Next.js Apps

Several static hosting platforms can easily host a static Next app.

  1. Vercel: This is a commonly used hosting platform. It provides built-in features and ease of use, making it great for hosting static and serverless Next.js applications. Vercel comes with global CDN support, quick integration, and auto-deployment.
  2. Firebase Hosting: This is provided by Google Firebase and supports static sites from Next.js. It also supports dynamic websites but provides seamless static hosting.
  3. Netfily: This option has one of the most straightforward setups and a developer-friendly interface. It supports continuous deployment, serverless functions, and form handling.
  4. GitHub Pages: GitHub pages are the easiest setup. You create a gh-pages branch, and it will work if you have an HTML source, but Nextjs doesn't do that. So, you can host your Next.js app by pre-rendering pages during the build process.
  5. Amazon Simple Storage Service (AWS S3): This can be used to host static websites. You have to configure an S3 bucket for static website hosting and then use AWS Cloudfront as a CDN for better performance.
  6. Render: This cloud hosting platform hosts static sites and covers serverless functions. It allows Next.js static sites to be hosted.

How to Deploy a Next.js app on a Static Hosting Platform

Deploying your static Next.js app on a static hosting platform is simple. Here are the steps to follow:

Step 1: Code your Next.js App

First, you must complete your Next.js code and ensure it's ready for deployment. It should be tested and work as expected.

Then, initialise your code and commit it to a Git repository.

Step 2: Pick a hosting platform

Now, you just need to choose any hosting platform like the one listed above. You'll only need a little configuration since it's static.

You can sign up for the free version or go pro.

Step 3. Connect your repository

When you log in to the hosting platform, you will find either "Connect a Repository" or "Import project" right after clicking Create a new project.

connecting repo to vercel
Importing a repo

Give the hosting platform permission to access your Git repository, and choose the repository with your Next.js application.

Step 4: Configure deployment settings

Now, you need to select the branch you want to deploy. Choose the build command. For a Next.js App, the build command is usually npm run build or yarn build.

Select the output directory. Since we are deploying a Next.js app, the output is typical, out or build.

Step 5: Deploy your app

Now it's time to deploy your app – the platform will handle the entire process. And then, it automatically builds your app's static files.

To deploy the app, click the Deploy button or the equivalent as presented by the hosting platform.

Step 6: Custom domain

Now, you can set up your custom domain from a third party or use the pro version if available.

Set up your Domain Name System (DNS) records of your custom domain to point to the hosting platform. (This step is optional.)

Step 7: Verify and test

Once deployment finishes, you'll get a Uniform Resource Locator (URL) from the hosting platform.

Visit the URL to confirm that your Next.js app is successfully deployed and works as expected. It should look something like this:

deployment tab
Deployment page on Vercel

Step 8: Continuous deployment

Lastly, it's a good time to implement a continuous deployment strategy if the static hosting platform allows it. This will allow your changes on the Git repository to be automatically deployed.

To do this, you must implement webhooks to trigger builds and deployments when new code is pushed.

Let's go through the steps for how you'd set up continuous deployment on GitHub:

  1. Go to the Repository settings of the project you want to deploy.
set the repo
A repository setting

2.  Select Webhooks on the left side

webhooks setting for repo
Select webhooks

3.  Click on Add webhook or New workflow

4. Configure the webhook

Provide the URL where the hosting platform will dump the webhook.

webhook
setting the webhook

5.  Select an event to trigger

As you can see, there are three events, and the one we need to pick is Just the Push event. This will trigger developments when new code is pushed.

6.  Add Secret

The secret is a password that adds an extra layer of security. It will be requested by the hosting platform as well.

7.  Save and Test

Save and test how the webhooks are being triggered when you push new code.

Option #2: Serverless Functions

Next.js projects can be integrated with serverless functions such as AWS Lambda using Vercel's serverless function or the serverless. With this option, developers can create dynamic server-side functionality without stressing over traditional server infrastructure management.

This deployment option helps handle form submission, API calls, and other server-side computations in a scalable and cheap manner.

There are a few platforms that support the serverless function option:

  • Amazon web services lambda
  • Azure functions
  • Google Cloud function
  • IBM cloud functions
  • Alibaba Cloud function
  • Vercel

These platforms simplify management and allow developers to focus more on coding than configuration.

Benefits of Serverless Function for Next.js App

Using the serverless function to host a Next.js app comes with several benefits that improve the performance, and they include:

  • Scalability: The serverless functions scale according to demand. They are built to handle sudden spikes in traffic and ensure that users get a consistent experience.
  • Cost efficiency: The serverless function's platform charges based on actual usage rather than maintaining dedicated servers, which helps save cost.
  • Microservices Architecture: Serverless functions allow you to create complex applications when you combine minor functions to solve a particular problem.
  • Faster development iterations: With serverless function, you can focus on specific features since they are isolated and quickly make changes without affecting the entire project.
  • Security and Isolation: Since serverless functions support an isolated environment, reducing the bug rate on one function affecting another, they are highly secured.
  • Global distribution: Serverless platforms are known to have a global network of data centres, which deploys your Next.js app's function closer to users and reduces latency.

Use cases of Serverless function for Next.js App.

Several websites benefit a lot from using a serverless function platform. Some types of these Next.js applications include:

  1. Forms and User Interactions apps: Using serverless functions to handle user logins, registrations, and other interactive elements can increase user experience and performance by making these processes seamless and asynchronous.
  2. Real-time Data fetching: Serverless functions can retrieve real-time information from a database or APIs without stressing your main server.
  3. Dynamic content: Use the serverless function hosting option when you have an app that generates personalised data such as charts, metrics, or user-specific content.
  4. Authentication and Authorization: Using a serverless function when authenticating and authorising data can improve security by offloading the heavy lifting of token validation and user management.
  5. E-commerce app: The serverless functions are great for handling shopping cart update orders and integrating smooth payment gateways.
  6. SEO optimisation: Using serverless functions to host your Next.js app helps render SEO metadata and improves search engine visibility.

Examples of Serverless hosting Hosting Platforms for Next.js Apps

We have listed several serverless function hosting platforms – now, let's discuss some popular ones.

  1. Vercel: Vercel is designed to fit Next.js needs seamlessly. It supports the serverless function and offers a global content delivery network (CDN), increasing performance and reliability.
  2. AWS Lambda: Amazon lambda is often used with Amazon API Getaway to allow you to deploy serverless functions and API. This option also allows you to build custom serverless architecture.
  3. Azure functions + Azure static web apps: This combination by Microsoft Azure cloud allows you to easily deploy your Next.js app with serverless functions.
  4. Google Cloud function and Firebase Hosting: You can combine Google Cloud and Firebase hosting to enjoy CDN capabilities and serverless functions when you deploy your Next.js app.
  5. Netlify: Netfily allows for easy deployment of Next.js applications and provides serverless functions. It supports form handling, continuous deployment and a version control system.

Exploring AWS Lambda's Serverless Deployment Option

AWS Lambda by Amazon Web Services allows you to run a serverless function without managing servers. It is commonly used to run code files in response to HTTP requests, data changes in the database, and other events.

Deploying your Nextjs application on AWS Lambda is simple if you use the Web Adapter provided by the platform. Let's go through the steps now.

Step 1: Package your Next.js application

Make sure your project is ready and tested locally. You can package your project as Zip files or a Docker image.

Choosing a Docker image means managing, building, or pushing any images. But the zip package style is simpler.

Let's first see how to do it with Docker.

Step 2: Dockerize Your App

First, you'll need to create a Dockerfile at the root of your project. Use a Node.js base image in the Dockerfile like so: FROM node:16.

Then, copy the Next.js app files/package into the container.

Install necessary dependencies using this command: RUN npm install --production. And then build the project with RUN npm build.

Specify the command to start the application: npm run start or yarn start

Step 3: Build the docker image

Now, use the docker build command in the terminal to create an image of your app and its dependencies.

Here is the command docker build -t my-nextjs-app .

  • -t; use to specify the tag of the image, which should be the name of the project
  • . to show that the docker should build with the current directory

Step 4: Push Image to Container Registry:

Push the Docker image so the AWS Lambda can easily access it. In this case, we push to Amazon Elastic Container Registry (ECR).

Login to AWS ECR:

aws ecr get-login-password --region region | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com

Tag the Docker Image:

docker tag image_name:tag aws_account_id.dkr.ecr.region.amazonaws.com/repository_name:tag

Push the image:

docker push aws_account_id.dkr.ecr.region.amazonaws.com/repository_name:tag

Step 5: Create AWS Lambda Function

From the AWS Lambda console, you will create a new lambda function. Select the Container image option and choose the docker image from the registry.

Now let's explore how to do it with the zip package:

Step 2: Build your Next.js App:

Use either npm run build or yarn build to build your Next.js app for production. This will build your raw .jsx files into HTML, CSS and Javascript code that will be presented to the user's browser.

Step 3: Create a Deployment package

Create the deploy directory and copy all needed files, including node_modules, package.json, and .next. This is all you need to have your Next.js app ready for production deployment.

Step 4: Create a zip package

Now, create the zip package with all your Next.js apps and dependencies. To do this, open your terminal and navigate to the directory of your production-ready app folder.

Then use the zip command zip -r my-nextjs-app.zip * ; this will zip the package in place and save it as my-nextjs-app.zip

If you are on Windows, use sudo apt-get install zip unzip to install the zip application.

Step 5: Upload the Zip package to AWS Lambda

In the AWS Lambda console, set up a new Lambda function. Choose the "Upload a .zip file" option and upload the zip package you created.

Here is how you upload the zip package to AWS Lambda

  1. Log in to your AWS management console, search Lambda in the services search bar
image-218
AWS lambda page

2. Click 'Create a function' to create a new lambda function.

3. Configure the function

  • Select the 'Author from scratch" option.
  • Input the function name.
  • Select the runtime; for the Next.js application, you will need Node.js.
image-220
Creating a lambda function
  • Select an execution role that grants full permission to the Lambda function and then click the 'create function' button.
image-221
Select an execution role.

4.  Configure function triggers: click 'Add trigger' and select the 'API Getaway' for the serverless option. And configure as you want.

image-222

5.  From the 'Code' tab under the 'Function overview' tab, click on the 'upload from' and select the '.zip file'. Find the saved my-nextjs-app.zip file and upload it.

image-223
Uploading the zip package

6.  More configuration and test: AWS management console allows you to configure 'destination', 'permission', 'function URL' and many more. You can also test your app under the test section.

image-227
Testing with AWS console

7.  Once you are satisfied with the configurations and settings, you can deploy it.

From now on, the steps will be the same, so let's continue the process:

Step 6: Configure Lambda Function:

You'll need to set your Lambda function's timeout, memory, and other configurations.

Then, define an environment variable (only when it's needed).

After that, you'll want to test your Lambda function and see if your Next.js App is running as expected.

Step 7: Configure API Getaway (optional)

If your project is an API, you can configure an API Gateway to act as the HTTP interface to your Lambda function.

Option #3: Containerization

This deployment option provides a way to package Next.js applications with their dependencies and make them smaller and more consistent across various environments.

You can containerise your Next.js app and deploy it via orchestration platforms like Kubernetes or Elastic Container Service (AWS ECS).

Benefits of Containerizing Next.js Applications

There are several benefits of using a containerisation deployment strategy for your Next.js app, which include:

  • Portability: The portability of containers allows developers to build once and run anywhere. This shrunk file can be helpful in a hybrid cloud or deployment environment.
  • Consistency: Containers allow your Next.js app to remain the same across all machines, staging, and testing. It reduces the "it doesn't work on my machine" problem.
  • Isolation: Containers isolate the system and other containers, improving security and minimising conflicts between your applications and their dependencies.
  • Microservices: The container has a microservices architecture that allows you to put out more minor parts of an application and manageable services that can be developed and tested independently.
  • Version Control: With container images, you can store and version them in the registries and make changes to upgrade to the next version or roll back to the previous version easily.
  • Fast Deployment: Contents allow you to start and shut down quickly, resulting in faster deployment and recovery times.
  • Infrastructure as Code (IaC): Containers work well with (IaC) practices, allowing you to set and manage your application's infrastructure via code.

How to Containerize and Deploy a Next.js App

We have touched on some steps for containerisation in the serverless function strategy section. Here are the complete steps required to deploy your Next.js app via containerisation.

Step 1: Dockerize your Next.js App

Create a Dockerfile at the root of your project. Use a Node.js base image in the Dockerfile like so: FROM node:16.

Copy the Next.js app files/package into the container and install the necessary dependencies with the command RUN npm install --production.

Build the project with this command: RUN npm build.

Then specify the command to start the application -- npm run start (CMD ["npm", "run"]).

Step 2: Build the Docker Image

Using the docker build command in the terminal, we can create an image of our app and its dependencies.

Then you'll want to test your Next.js app using the docker run -p 3000:3000 nextjs-app command and be sure it works as expected.

Step 3: Deploy the containerised Next.js App

Select where to store your docker image – you can use Amazon ECR, Docker Hub, Google Container Registry, etc.

Next, you'll want to tag and push the Docker image. Use the command docker tag nextjs-app:latest registry-url/repository-name:tag.

Replace the registry-url/repository-name:tag with your selected registry platform and values.

Next, push the finish tag image to the chosen registry with this command:
docker push registry-url/repository-name:tag.

Step 4: Set up your Deployment environment

Configure the environment on your chosen cloud provider. Follow this steps

  • Choose a cloud provider like Amazon Web Services (AWS), Google Cloud Platform, Microsoft Azure or any that fits your budget and requirements. Create and log in to your account.
  • Set up a container registry on the selected provider.
  • Configure the security and subnets and create virtual networks, as they will control the network access to your containerised app.

Step 5: Deploy your App

Now, deploy your Next.js app using either:

  • Kubernetes: Apply the YAML file like so kubectl apply -f filename.yaml
  • AWS ECS: Create a new task using the AWS management console or AWS CLI

Next, you'll need to configure Ingress or Load Balancer to make your app available online. And finally, you'll want to test your deployed Next app.

Option #4: Edge-Side Rendering (ESR)

This deployment option provides the Next.js app with edge-side rendering to get cached versions of pages from a content delivery network (CDN).

The CDN makes the pages load faster when a user requests a page the second time. This is possible because the CDN delivers pre-rendered pages, reducing response time.

Benefits of Edge-Side Rendering (ESR) When Deploying a Next.js App

Edge-side rendering renders part of the user interface at the edge servers of a CDN, but that's not the only benefit. Other benefits include:

  1. Improved performance: ESR decreases the website's loading time by minimising the round-trip time to the origin server. This produces faster loading time and improved user experience.
  2. Reduced latency: ESR loads content from a closer server, and even when the origin server is far away, users receive content quickly.
  3. Enhanced Search Engine Optimisation (SEO): SEO is improved because the search engine can crawl pre-rendered HTML content from edge servers.
  4. Scalability: ESR shares the rendering load with origin and edge servers, which helps handle more users during traffic spikes without overworking the origin server or crashing.
  5. Lower Server Load: ESR allows the origin server to be responsible for only some users' rendering requests. ESR reduces resource consumption and server load and improves overall performance.
  6. Consistent User Experience: ESR ensures that all devices, regardless of browser capabilities, receive rendered content, providing a consistent experience.
  7. Cost savings: By using edge servers, you will spend less power and resources on the origin servers.

How to Deploy a Next.js App with Edge-Side Rendering (ESR)

Deploying a Next.js app with Edge-side Rendering requires a CDN to render some parts of your Next.js app with edge servers. Here is how the process works.

Step 1: Prepare your Next.js App

Be sure that your Next.js app is functional and has been tested locally. Ensure it is ready to be deployed.

Step 2: Choose your CDN provider

Choose a CDN provider with ESR support. You can pick Cloudflare Workers, Vercel Edge Network, or Fastly. Decide which best fits your app.

Step 3: Set up the CDN Account

Set up your CDN account, which should only take about five minutes.

  • Sign up or log in to your preferred CDN provider above.
  • Select a plan that fits your budget and app's requirements.

Step 4: Configure Edge-side Rendering

Configure ESR with the instructions given by the CDN provider. The process involves writing scripts that tell which part of your Next.js app should be rendered on the edge server and which parts can be served on the origin server.

Step 5: Deploy the ESR Configuration

Deploy your ESR configuration to the selected CDN platform using the appropriate command on the CLI – vercel deploy, wrangler publish, and so on.

Step 6: Test Edge-side Rendering:

Test the ESR configuration and confirm that the specified parts of your app are being rendered on the edge server. Watch the performance improvements and ensure the rendering is consistent across various devices, browsers, and locations.

Step 7: Update DNS Settings

Set up the DNS setting to point to the CDN's servers to ensure requests to your app are routed through the edge servers.

Step 8: Monitor and Optimise:

Once deployed, monitor the performance in real life. Check the monitoring tools provided by the CDN to track the metrics, latency, and user experience.

Note that the steps may change depending on the CDN provider you selected, but these are the basic steps for all. You can check the documentation to learn more.

Best Practices for Next.js Application Deployment

Deploying a Next.js app is similar to deploying any other web app. Although Next.js allows backend development, the deployment strategies are almost identical.

To deploy your Next.js apps in the best and most efficient way possible, consider the following practices:

  1. Optimised Builds: Optimising the build process of your Next.js by using the best build setting, leveraging static site generation (SSR) or server-side rendering (SSR).
  2. Error Tracking: Integrate tools to find and solve issues proactively. Monitor server health, user interaction, and application to improve user experience and application stability.
  3. Environment Variables: Managing sensitive information API and config should be done in an environment variable. Avoid putting sensitive data into your codebase during any deployment environment.
  4. Continuous Integration and Continuous Deployment (CI/CD):  To decrease bugs and errors in your deployed Next.js application, you must set up CI/CD pipelines. These pipelines will automate the process of building, deploying, and testing your project.
  5. Scalability Considerations: A well-designed architecture should be in place to handle increased traffic. Leverage techniques such as serverless function and caching mechanics in your application to manage fluctuations in user demand.
  6. Automated Testing: Do automated testing for your application to check for performance and functionality. You can try unit tests, integration tests, and end-to-end tests to catch bugs earlier while still in the deployment stage.
  7. Version Control: Use a system like Git to track changes in your codebase and enhance collaboration with teammates. With a version control platform, you can easily undo errors and bugs and integrate features.
  8. Documentation: A well-detailed document about the installation instructions, deployment, and configuration of your Next.js application. This adequately written documentation will help onboard new members and streamline the deployment process.
    These practices are incredible and help achieve a smooth and scalable application.

Best Practices for Handling Environment Variables in a Next.js App

We must talk about best practices and pay attention to security. Managing environment variables is crucial for security and configuration management when deploying your Next.js app.

Here are some best practices:

  1. Use .env.local for local deployment: Create a .env.local file at the root of your project. This file will contain variables to be used only during local deployment.
  2. Use .env for Shared Variables: Here, you can store non-sensitive variables committed to version control and share them with the team. Create a .env file, but don't store sensitive information here.
  3. Use .env.production for production: The .env.production file contains variables needed during your app's building process. These variables in the .env.production file take precedence over those in the .env file.
  4. Server-side Access: Some variables stored in the .env file should only be accessed server-side to prevent exposing them to the client. You can use the getServerSideProps or getInitialProps methods to set it.
  5. Version Control exclusion: Don't commit variables; include them in a gitignore file to prevent security issues.
  6. CI/CD integration: Use CI/CD pipelines to manage the environment variables and ensure consistent configuration securely.

Conclusion

Deployment is as vital as any stage of creating a Next.js app; one could argue that it is the most important because a wrong configuration during deployment could affect your app's performance and drive users away.

The strategies are similar but unique, and the one you select should depend on the kind of website you create. You don't need to choose the Edge-server rendering strategy when you make a static website.

Follow the best practices above to deploy a safe and optimised Nezt.js app for your users.

Additional resources: