Next.js, Vercel, and GitHub Actions logos with 'Deploy Next.js to Vercel using GitHub Actions' text on a gradient background.

Published: Jul 28, 2024

Last Updated: Aug 1, 2024

Deploying Next.js to Vercel with GitHub Actions: A Quick Guide

Continuous Integration and Continuous Deployment (CI/CD) have become vital in modern web development, ensuring quick, efficient, and reliable code deployments. CI/CD automates the process of testing, building, and deploying code, reducing manual intervention and potential errors.

Vercel is a platform that makes it easy for developers to host websites and web applications, with built-in support for Next.js. While Vercel allows linking repositories directly through its dashboard, using GitHub Actions provides a more flexible and powerful way to customize your deployment process. This guide will help you deploy a Next.js application to Vercel using GitHub Actions, streamlining your development workflow.

Prerequisites

Before we begin, make sure you have the following:

  • GitHub account: To host your code and configure Actions.
  • Vercel account: To deploy and host your Next.js application.
  • Node.js and npm: Ensure you have Node.js installed to manage dependencies.
  • Next.js: Basic knowledge and an initial Next.js project setup.

Setting Up Your Next.js App

First, set up a new Next.js project:

SH
# create nextjs app
npx create-next-app deploy-nextjs-app-to-vercel --ts --eslint --app --src-dir --use-pnpm --no-tailwind --no-import-alias
#  Navigate to the created nextjs app
cd deploy-nextjs-app-to-vercel
# install dependencies 
pnpm install
# starts the development server.
npm run dev

This command initializes a new Next.js project and starts the development server.

Creating a GitHub Repository

  1. Go to GitHub and sign in.
  2. Click the New button to create a new repository.
  3. Name your repository (e.g., deploy-nextjs-app-to-vercel) and choose its visibility (public or private).
  4. Follow the prompts to create the repository.
  5. Initialize your local project as a Git repository and push it to GitHub:
SH
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/yourusername/my-nextjs-app.git
git push -u origin main

Creating a Vercel Project

  • Go to Vercel and sign in.
  • Click on the New Project button.
  • If your repository appears in the list, select it. If not, click on Missing Git repository? Adjust GitHub App Permissions →.
  • Follow the prompts to adjust permissions and ensure Vercel has access to your repository.
  • Follow the prompts to set up the project, ensuring Vercel can access the repo.
  • Once your repository is connected, follow the setup prompts to configure your project.
  • Add a vercel.json file to the project root to prevent Vercel from building the project:
JSON
{
  "github": {
    "enabled": false,
    "silent": true
  }
}

Add this file to your project’s root directory:

Configuring GitHub Actions

GitHub Actions automates your workflows. We'll use the following actions:

Create a .github/workflows/deploy.yml file in your repository:

YAML
name: Deployment

on:
  push:
    branches: [main]
  pull_request:

jobs:
  vercel:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [20.x]

    steps:
      - name: Checkout
        uses: actions/checkout@v4.1.7

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4.0.3
        with:
          node-version: ${{ matrix.node-version }}

      - uses: pnpm/action-setup@v2.4.1
        name: Install pnpm
        id: pnpm-install
        with:
          version: 7
          run_install: false

      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

      - uses: actions/cache@v4.0.2
        name: Setup pnpm cache
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-

      - name: Install dependencies
        run: pnpm install --no-frozen-lockfile

      - name: Build
        run: pnpm build

      - name: Lint
        run: pnpm lint
# Initializes a deployment status for preview environments.
# Runs for all branches except main.
      - name: Start Deployment
        uses: bobheadxi/deployments@v1.5.0
        id: deployment-preview
        with:
          step: start
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          env: Preview
# Deploys the app to Vercel as a preview deployment.
# Runs for all branches except main.
      - name: Deploy to Preview
        id: vercel-action-preview
        if: github.ref != 'refs/heads/main'
        uses: amondnet/vercel-action@v25.2.0
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          scope: ${{ secrets.VERCEL_ORG_ID }}
          github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
# Deploys the app to Vercel in production mode.
# Runs only when changes are pushed to the main branch.
      - name: Deploy to Production
        uses: amondnet/vercel-action@v25.2.0
        id: vercel-action-production
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          scope: ${{ secrets.VERCEL_ORG_ID }}
          github-comment: false
          vercel-args: "--prod"
          github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
# Finalizes the deployment status with the URL of the deployed preview.
# Runs for all branches except main.
      - name: Update Deployment Status
        uses: bobheadxi/deployments@v1.5.0
        if: github.ref != 'refs/heads/main'
        with:
          step: finish
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          status: ${{ job.status }}
          deployment_id: ${{ steps.deployment-preview.outputs.deployment_id }}
          env_url: ${{ steps.vercel-action-preview.outputs.preview-url }}
          env: ${{ steps.deployment-preview.outputs.env }}

Setting Up Vercel Environment Variables

To deploy your Next.js application using GitHub Actions, you must obtain and configure Vercel environment variables. Here’s how:

  • Generate a Vercel Token:
    • Go to your Vercel Account Settings and navigate to the Tokens section.
    • Click on Generate Token and copy the generated token.
  • Find Your Vercel Org ID and Project ID:
    • Using Vercel CLI:
      • Link your local project to Vercel:
        npx vercel link
      • Follow the interactive prompts. This command will create a .vercel/project.json file in your project directory containing your orgId and projectId.
JSON
{
  "orgId": "your-org-id",
  "projectId": "your-project-id"
}

Generating a Personal Access Token (PAT) with Fine-Grained Permissions:

  • Go to your GitHub settings.
  • Click on Generate new token.
  • Choose Fine-grained token and set the following:
    • Repository permissions:
      • Actions: Read and write
      • Deployments: Read and write
      • Contents: Read and write
      • Metadata: Read-only
      • Issues: Read and write
      • Pull requests: Read and write
  • Generate the token and copy it

Add Vercel Environment Variables to GitHub:

  • Go to Settings > Secrets and variables > Actions in your GitHub repository.
  • Add the following secrets with their corresponding values:
    • VERCEL_TOKEN: The token you generated from Vercel.
    • VERCEL_ORG_ID: The orgId from .vercel/project.json.
    • VERCEL_PROJECT_ID: The projectId from .vercel/project.json.
    • PERSONAL_ACCESS_TOKEN: The GitHub PAT you generated.

Testing and Troubleshooting

After setting everything up, it’s crucial to test both preview and production deployments.

Testing Preview Deployment:


Create a new branch and push changes by running:

SH
git checkout -b set-up-deployment
git add .
git commit -m "Set up deployment"
git push origin set-up-deployment

Open a pull request (PR) on GitHub and verify the deployment in the Actions tab to ensure it completes successfully. Check the preview deployment on Vercel using the URL provided in the PR.

Testing Production Deployment

Merge the PR into the main branch. Verify the deployment in the Actions tab to ensure it completes successfully. Check the production deployment on Vercel.

Common Issues:

  • Resource not accessible by integration: Ensure your Personal Access Token has the necessary permissions.
  • Build failures: Check the logs in the Actions tab for details on what might be going wrong.

Conclusion

You've successfully set up a CI/CD pipeline, deploying your Next.js app to Vercel using GitHub Actions. This setup ensures automated deployments, saving time and reducing human error, which is essential for efficient development workflows.

Resources

For further reading and to deepen your understanding, here are some valuable resources:

  • Next.js Documentation: Comprehensive guides and API references to help you build and optimize your Next.js applications.
  • Vercel Documentation: Detailed information on deploying and managing your projects on Vercel, including advanced configuration options.
  • GitHub Actions Documentation: Official documentation on setting up and using GitHub Actions for CI/CD, with examples and best practices.
  • Vercel CLI: Learn how to use the Vercel CLI for more advanced project configurations and management.
  • GitHub Secrets Management: Best practices for managing secrets and sensitive data within your GitHub workflows.
  • Repository Example: Access the example repository used in this guide for reference and further exploration.