We use cookies to enhance your experience on the site
CodeWorlds

Deployment on Vercel, Netlify, and other platforms

After creating a Next.js application, a key stage is deploying it to the production environment. In this module, we will look at various hosting platforms that offer an optimized environment for Next.js applications, with a particular focus on Vercel - the platform created by the Next.js authors.

Deployment on Vercel

Vercel is a platform that offers the best native support for Next.js applications, as both technologies are developed by the same company. This ensures optimal support for all Next.js features, automated deployments, and a global CDN.

Project preparation

Before deploying, ensure that your project is ready for production:

  1. Checking environment variables - ensure that all environment variables are properly configured
  2. Initial optimization - run
    next build
    locally to check for potential errors
  3. Version control - ensure that your project is in a Git repository (GitHub, GitLab or Bitbucket)

Step by step: Deployment on Vercel

  1. Create an account on Vercel

    • Go to vercel.com and sign up, preferably using a GitHub/GitLab/Bitbucket account
  2. Import the project

    • After logging in, click "Add New..." > "Project"
    • Select your repository from the list
  3. Deployment configuration

    • Vercel automatically detects that the project is a Next.js application
    • You can customize the project name, deployment branch, and environment variables
    • For standard Next.js projects, the default settings are usually sufficient
  4. Deployment

    • Click "Deploy"
    • Vercel will build and deploy your application, optimizing it for production
  5. Deployment verification

    • After a successful deployment, you will receive a unique URL
    • Check your application and ensure that everything works correctly

Custom domain configuration

To configure a custom domain for your project on Vercel:

  1. Go to the project panel
  2. Select the tab "Domains"
  3. Click "Add" and enter your domain name
  4. Follow the instructions to configure the DNS records:
    • For root domains (e.g., example.com): Create an A record pointing to Vercel's IP
    • For subdomains (e.g., www.example.com): Create a CNAME record pointing to the Vercel domain

Automatic deployments and previews

One of Vercel's greatest strengths is the automatic deployment system:

  1. Automatic production deployments

    • Each push to the main branch (e.g.,
      main
      ) triggers an automatic deployment
  2. Preview Deployments

    • Each pull request automatically creates a unique preview environment
    • This allows testing changes before merging with the main branch
1// Example of Next.js configuration optimized for Vercel
2// next.config.js
3
4module.exports = {
5  // Image optimization - automatically handled by Vercel Image Optimization
6  images: {
7    domains: ['example.com', 'images.unsplash.com'],
8  },
9  
10  // Integrated Vercel analytics
11  vercelAnalytics: {
12    enabled: true,
13  },
14  
15  // Internationalization settings
16  i18n: {
17    locales: ['pl', 'en', 'de'],
18    defaultLocale: 'pl',
19  },
20};

Advanced Vercel features

Vercel offers a range of advanced features worth using:

  1. Edge Functions - running code close to the user on Vercel's global edge network
  2. Serverless Functions - automatic conversion of API Routes into serverless functions
  3. Edge Middleware - running middleware at the network edge
  4. Edge Config - storing configuration at the edge with ultra-fast reads
  5. Analytics - built-in analytics tools
  6. Speed Insights - monitoring Core Web Vitals

Deployment on Netlify

Netlify is another popular platform that offers excellent support for Next.js applications, especially after the introduction of the Netlify Next.js Runtime feature.

Project preparation for Netlify

  1. Create the netlify.toml configuration file in the project's main directory:
1# netlify.toml
2[build]
3  command = "npm run build"
4  publish = ".next"
5
6[[plugins]]
7  package = "@netlify/plugin-nextjs"
  1. Install the Next.js plugin for Netlify:
1npm install -D @netlify/plugin-nextjs
2# or
3yarn add -D @netlify/plugin-nextjs

Step by step: Deployment on Netlify

  1. Create an account on Netlify

  2. Import the project

    • Click "Add new site" > "Import an existing project"
    • Connect to your Git provider and select your repository
  3. Deployment configuration

    • Netlify should automatically detect the Next.js project settings
    • Make sure the build command is
      npm run build
      or
      yarn build
    • The publish directory should be set to
      .next
  4. Configure environment variables

    • Go to "Site settings" > "Build & deploy" > "Environment"
    • Add all needed environment variables
  5. Deployment

    • Click "Deploy site"

Netlify-specific features

Netlify offers a range of unique features that can be useful in Next.js projects:

  1. Netlify Functions - the equivalent of API Routes
  2. Netlify Edge Functions - similar to Next.js Middleware, but running at the edge
  3. Netlify Forms - built-in form handling without the need to create API endpoints
  4. Netlify Identity - user authentication service
1// Example of using Netlify Functions with Next.js
2// /netlify/functions/hello-world.js
3
4exports.handler = async function(event, context) {
5  return {
6    statusCode: 200,
7    body: JSON.stringify({ message: "Hello World" }),
8    headers: {
9      'Content-Type': 'application/json'
10    }
11  };
12};
13
14// Access from the Next.js application
15// pages/api-example.js
16import { useState, useEffect } from 'react';
17
18export default function ApiExample() {
19  const [data, setData] = useState(null);
20  
21  useEffect(() => {
22    fetch('/.netlify/functions/hello-world')
23      .then(res => res.json())
24      .then(data => setData(data));
25  }, []);
26  
27  return (
28    <div>
29      <h1>API Example</h1>
30      <pre>{JSON.stringify(data, null, 2)}</pre>
31    </div>
32  );
33}

Deployment on AWS Amplify

AWS Amplify is a service from Amazon that also offers good support for Next.js applications, especially if you already use the AWS ecosystem.

Project preparation for AWS Amplify

  1. Create the amplify.yml file in the project's main directory:
1# amplify.yml
2version: 1
3frontend:
4  phases:
5    preBuild:
6      commands:
7        - npm ci
8    build:
9      commands:
10        - npm run build
11  artifacts:
12    baseDirectory: .next
13    files:
14      - '**/*'
15  cache:
16    paths:
17      - node_modules/**/*

Step by step: Deployment on AWS Amplify

  1. Create an AWS account or log in to an existing one

  2. Go to the AWS Amplify console

    • Select "Host web app"
  3. Connect the repository

    • Select a repository provider (GitHub, GitLab, BitBucket, or AWS CodeCommit repository)
    • Log in and select your repository
  4. Build settings configuration

    • Amplify should automatically detect the Next.js framework
    • You can adjust or confirm the build settings
  5. Configure environment variables

    • Add all needed environment variables in the "Environment variables" section
  6. Deployment

    • Click "Save and deploy"

Integration with AWS services

One of the main strengths of AWS Amplify is easy integration with other AWS services:

1// Example: Integration with AWS Lambda and DynamoDB
2// pages/api/users.js
3
4import { DynamoDB } from 'aws-sdk';
5
6const dynamoDB = new DynamoDB.DocumentClient();
7
8export default async function handler(req, res) {
9  if (req.method === 'GET') {
10    const params = {
11      TableName: process.env.DYNAMODB_TABLE_NAME,
12    };
13    
14    try {
15      const data = await dynamoDB.scan(params).promise();
16      res.status(200).json(data.Items);
17    } catch (error) {
18      res.status(500).json({ error: 'Failed to fetch users' });
19    }
20  }
21}

Deployment on Digital Ocean App Platform

Digital Ocean App Platform is another hosting option that offers good support for Next.js applications.

Step by step: Deploying on Digital Ocean

  1. Create a Digital Ocean account or log in to an existing one

  2. Go to Digital Ocean App Platform

    • Click "Create App"
  3. Select the code source

    • Connect your GitHub, GitLab repository, or choose another source
  4. Application configuration

    • Select the branch to deploy
    • Select the application type as "Web Service"
    • In the build settings, select "Next.js" as the example application
  5. Adjust the settings

    • Set the build command to
      npm run build
      or
      yarn build
    • Set the run command to
      npm start
      or
      yarn start
  6. Finalization

    • Select a pricing plan
    • Click "Launch App"

Other hosting options for Next.js

GitHub Pages with GitHub Actions

For statically generated Next.js applications, you can use GitHub Pages with GitHub Actions:

  1. Create a GitHub Actions workflow file:
1# .github/workflows/deploy.yml
2name: Deploy to GitHub Pages
3
4on:
5  push:
6    branches: [ main ]
7
8jobs:
9  build:
10    runs-on: ubuntu-latest
11    steps:
12      - uses: actions/checkout@v2
13      - uses: actions/setup-node@v2
14        with:
15          node-version: '18'
16      - name: Install dependencies
17        run: npm ci
18      - name: Build and export
19        run: npm run build && npm run export
20      - name: Deploy
21        uses: peaceiris/actions-gh-pages@v3
22        with:
23          github_token: ${{ secrets.GITHUB_TOKEN }}
24          publish_dir: ./out
  1. Adjust next.config.js:
1// next.config.js
2module.exports = {
3  output: 'export',
4  basePath: '/repository-name', // If the page is not on the main domain
5  images: {
6    unoptimized: true, // For GitHub Pages
7  },
8};
  1. Add a script to package.json:
1{
2  "scripts": {
3    "export": "next export"
4  }
5}

Firebase Hosting

Firebase Hosting is another option, especially if you use other Firebase services:

  1. Install the Firebase CLI:
1npm install -g firebase-tools
  1. Initialize the Firebase project:
1firebase login
2firebase init hosting
  1. Configure the firebase.json file:
1{
2  "hosting": {
3    "public": "out",
4    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
5    "rewrites": [
6      {
7        "source": "**",
8        "destination": "/index.html"
9      }
10    ]
11  }
12}
  1. Build and deploy the application:
1npm run build
2npm run export
3firebase deploy

Self-hosting on your own server

If you prefer to host the application on your own server:

Node.js server

  1. Prepare the start script in package.json:
1{
2  "scripts": {
3    "start": "next start -p $PORT"
4  }
5}
  1. Use PM2 to manage the process:
1npm install -g pm2
2pm2 start npm --name "next-app" -- start
  1. Configuring Nginx as a reverse proxy:
1server {
2  listen 80;
3  server_name yourpage.com www.yourpage.com;
4
5  location / {
6    proxy_pass http://localhost:3000;
7    proxy_http_version 1.1;
8    proxy_set_header Upgrade $http_upgrade;
9    proxy_set_header Connection 'upgrade';
10    proxy_set_header Host $host;
11    proxy_cache_bypass $http_upgrade;
12  }
13}

Containerization with Docker

  1. Create a Dockerfile:
1# Dockerfile
2FROM node:18-alpine AS base
3
4# Dependency installation stage
5FROM base AS deps
6WORKDIR /app
7COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
8RUN   
9  if [ -f yarn.lock ]; then yarn --frozen-lockfile;   
10  elif [ -f package-lock.json ]; then npm ci;   
11  elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i;   
12  else echo "No lockfile present" && exit 1;   
13  fi
14
15# Build stage
16FROM base AS builder
17WORKDIR /app
18COPY --from=deps /app/node_modules ./node_modules
19COPY . .
20RUN npm run build
21
22# Production stage
23FROM base AS runner
24WORKDIR /app
25ENV NODE_ENV production
26
27RUN addgroup --system --gid 1001 nodejs
28RUN adduser --system --uid 1001 nextjs
29
30COPY --from=builder /app/public ./public
31COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
32COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
33
34USER nextjs
35EXPOSE 3000
36ENV PORT 3000
37
38CMD ["node", "server.js"]
  1. Configure next.config.js:
1// next.config.js
2module.exports = {
3  output: 'standalone',
4};
  1. Build and run the container:
1docker build -t next-app .
2docker run -p 3000:3000 next-app

Best practices

Environment variables

Manage environment variables according to Next.js best practices:

  1. Distinguish between client and server variables:

    • Variables that should be available in the browser should have the prefix
      NEXT_PUBLIC_
    • The remaining variables are available only in server code
  2. Environment files:

    • .env.local
      - variables for the local environment, not committed to the repository
    • .env.development
      - variables for the development environment
    • .env.production
      - variables for the production environment
    • .env.test
      - variables for the test environment

Deployment optimization

  1. Cache and CDN:

    • Configure appropriate cache headers for static resources
    • Use a CDN to speed up the delivery of static resources
  2. Compression:

    • Enable Gzip or Brotli compression on the server
  3. Core Web Vitals:

    • Monitor Web Vitals metrics after deployment
    • Use tools like Lighthouse or PageSpeed Insights
1// next.config.js - production optimization
2module.exports = {
3  // Compression
4  compress: true,
5  
6  // Image optimization
7  images: {
8    domains: ['images.example.com'],
9    formats: ['image/avif', 'image/webp'],
10  },
11  
12  // Static generator - maximum performance for ISR/SSG pages
13  staticPageGenerationTimeout: 120,
14  
15  // Production optimization
16  productionBrowserSourceMaps: false, // Disable source maps in production
17  
18  // webpack configuration
19  webpack: (config, { dev, isServer }) => {
20    // webpack optimizations...
21    return config;
22  },
23};

Deployment automation

Consider implementing Continuous Deployment (CD) to automate the deployment process:

1# GitHub Actions - deploy.yml
2name: Deploy
3
4on:
5  push:
6    branches: [ main ]
7
8jobs:
9  deploy:
10    runs-on: ubuntu-latest
11    steps:
12      - uses: actions/checkout@v2
13      
14      - name: Setup Node.js
15        uses: actions/setup-node@v2
16        with:
17          node-version: '18'
18          
19      - name: Install dependencies
20        run: npm ci
21      
22      - name: Run tests
23        run: npm test
24      
25      - name: Build project
26        run: npm run build
27      
28      - name: Deploy to production
29        uses: amondnet/vercel-action@v20
30        with:
31          vercel-token: ${{ secrets.VERCEL_TOKEN }}
32          vercel-org-id: ${{ secrets.ORG_ID }}
33          vercel-project-id: ${{ secrets.PROJECT_ID }}
34          vercel-args: '--prod'

Summary

Next.js application deployment can be done in many ways, depending on the project's needs and the team's preferences:

  1. Vercel - the best native support, optimized for Next.js
  2. Netlify - strong competitor with good Next.js support and additional features
  3. AWS Amplify - good choice for users of the AWS ecosystem
  4. Digital Ocean App Platform - simple PaaS platform with good Next.js support
  5. Self-hosting - ability to have full control over the infrastructure

The choice of hosting platform should be tailored to:

  • The specifics of the project and its technical requirements
  • Budget and expected costs
  • The team's experience with the given platform
  • Needs related to scalability and performance
  • Additional services and integrations that may be needed

Regardless of the chosen platform, it's worth following best practices for managing environments, environment variables, security, and deployment automation.

Go to CodeWorlds