DEV Community

Cover image for Mastering vercel.json with Frontend + Backend Projects on Vercel
Mahmudur Rahman
Mahmudur Rahman

Posted on

Mastering vercel.json with Frontend + Backend Projects on Vercel

Deploying modern applications often means working with two separate codebases:

  • A frontend (React, Vue, Next.js, etc.)

  • A backend (Node.js/Express APIs, or any server logic)

On Vercel, you can easily deploy both from the same project if you configure the file correctly. In this guide, we’ll cover everything you need to know, from beginner basics to advanced configuration.


What is vercel.json?

The vercel.json file is a blueprint for deployment. It tells Vercel:

  • Where your frontend lives

  • Where your backend lives

  • How to build and serve both

  • How to handle routing, rewrites, redirects, headers, caching, and more

Without it, Vercel will guess — but with it, you’re in full control.


The Common Folder Structure

Let’s assume your repo looks like this:

my-project/
│
├── client/       # React / Vue / Next.js frontend
│   ├── package.json
│   └── src/
│
├── server/       # Node.js backend
│   ├── index.js
│   └── routes/
│
└── vercel.json   # The config file

Enter fullscreen mode Exit fullscreen mode

We want:

  • Frontend to deploy as a static site (React/Vue) or a Next.js app.

  • Backend to deploy as API endpoints.


Example vercel.json for Frontend + Backend

Here’s a working configuration:

{
  "version": 3,
  "installCommand": "npm install --legacy-peer-deps",
  "builds": [
    {
      "src": "server/index.js",
      "use": "@vercel/node"
    },
    {
      "src": "client/package.json",
      "use": "@vercel/static-build",
      "config": { "distDir": "build" }
    }
  ],
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "server/index.js"
    },
    {
      "src": "/(.*)",
      "dest": "client/build/$1"
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Builds section

    • server/index.js → runs with Node (@vercel/node)
    • client/package.json → tells Vercel this is a frontend project, builds with npm run build, and outputs to client/build
  • Routes section

    • /api/* → requests go to the backend server
    • Anything else (/(.*)) → served from frontend build folder

Result:

  • https://yourapp.vercel.app/api/users → handled by backend

  • https://yourapp.vercel.app/about → handled by frontend


Key Features You Should Know

Let’s go deeper into everything you can configure in vercel.json.


1. Rewrites (for SPA routing)

If you’re using React, Vue, or Angular → you need rewrites so your frontend router works:

{
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

Enter fullscreen mode Exit fullscreen mode

Now /dashboard or /profile/123 won’t break — they’ll still load index.html.


2. Redirects (SEO + URL management)

{
  "redirects": [
    { "source": "/docs", "destination": "/documentation", "permanent": true }
  ]
}

Enter fullscreen mode Exit fullscreen mode
  • Useful for moving old pages to new URLs.

  • permanent: true gives a 301 redirect (SEO-friendly).


3. Headers (security, caching, CORS)

{
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Origin", "value": "*" }
      ]
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

Great for APIs that require CORS or additional security headers.


4. Clean URLs

{
  "cleanUrls": true
}

Enter fullscreen mode Exit fullscreen mode

Removes .html/about.html becomes /about.


5. Trailing Slash

{
  "trailingSlash": false
}

Enter fullscreen mode Exit fullscreen mode
  • false/about

  • true/about/

Pick one and keep it consistent.


6. Environment Variables

Though not in vercel.jsonyou’ll often combine configurations with Vercel Dashboard environment variables.

Example in backend code:

const db = process.env.DATABASE_URL;

Enter fullscreen mode Exit fullscreen mode

Set it inside Vercel → Project Settings → Environment Variables.


7. Multiple Frontends + APIs

If you have more than one frontend (e.g., admin + client) with a shared backend, you can extend your builds:

{
  "version": 3,
  "builds": [
    { "src": "server/index.js", "use": "@vercel/node" },
    { "src": "client/package.json", "use": "@vercel/static-build", "config": { "distDir": "build" } },
    { "src": "admin/package.json", "use": "@vercel/static-build", "config": { "distDir": "build" } }
  ],
  "routes": [
    { "src": "/api/(.*)", "dest": "server/index.js" },
    { "src": "/admin/(.*)", "dest": "admin/build/$1" },
    { "src": "/(.*)", "dest": "client/build/$1" }
  ]
}

Enter fullscreen mode Exit fullscreen mode

Now /admin serves the admin frontend, / serves the client frontend, and /api serves your backend.


Pro Tips

  • Test locally: run vercel dev and make sure routes are correct.

  • Keep your frontend and backend in separate folders.

  • Always define routes for APIs first, then the frontend.

  • Use rewrites for SPA apps, redirects for SEO, and headers for security.

  • Keep a clean, minimal config, don’t overcomplicate unless needed.


🎯 Final Thoughts

With vercel.json, you can:

  • Deploy frontend + backend in one project

  • Control routes, headers, caching, redirects

  • Scale your app without changing project structure

Whether you’re deploying a simple React app or a full MERN stack, mastering this file ensures deployments are smooth, predictable, and professional.


Top comments (0)