Deploy Nest.js on Vercel

Yosif Yosifov
3 min readMar 12, 2024

--

When should you consider deploying Nest.js on Vercel?

Vercel provides infrastructure and services for quick and easy setup of deployments of Next.js applications. However, it is serverless and can be used to host Node.js applications (express or any other framework) or Nest.js, too.

Vercel hasn’t been designed to host backend applications. But, there are a few reasons you might still want to give it a try:

  • Next.js is great for frontend apps, but is not convenient for robust backend APIs — a lot of node modules are not running on the Edge (an example is the MongoDB driver).
  • Cloud providers — if you already use Vercel for your Next.js project, it makes sense to try to utilize it for the Backend as far as it suits you. You won’t need to explore the vast options in AWS for example — there you have a bunch of options- ec2, ECS, EKS, fargate, beanstalk, etc.
  • Quick and easy setup of deployments upon push in Git, which works out of the box. This saves you time in thinking/implementing CI/CD actions
  • It’s quick for prototyping and getting a project off the ground when you want to build a product, not invest heavily into architecture from the beginning
  • Very easy setup of domains and SSL certificates — out of the box, yet again
  • Has neat monitoring — out of the box provides runtime logs, analytics, and monitoring

Deploying a Nest.js Application

The easiest way to deploy a Nest.js application is to:

  1. Add a vercel.json file in the root folder of your Nest.js project. An example config with Nest.js 10
{
"version": 2,
"builds": [
{
"src": "src/main.ts",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "src/main.ts"
}
]
}

2. Configure a new Project in Vercel of type “Other” and point it to the directory with your Nest.js project

3. The settings should be picked up from the vercel.json and you can see this in the Settings tab. To change settings — update the vercel.json instead of using the UI

4. Configure a custom Domain if you have one and you’re done!

CORS

If you have a Next.js + Nest.js setup, you’ll need to call the Backend API from the Frontend application from the Browser (with fetch).

In that case, as they are hosted on different domains, you’d have to configure CORS. It’s a little bit hacky for Vercel, as it wasn’t designed to host backend applications. It took me quite a while to troubleshoot and make it work, so here are the steps:

  1. Enable the CORS in your next.js application in the bootstrap() of your application like this:
app.enableCors({
origin: process.env.FRONTEND_URL, // Add your frontend URL here
methods: [ "GET", "POST", "PUT", "DELETE","OPTIONS", "PATCH"],
allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'],
});

Assuming you’re using express in Nest.js, you can see all the different options in the CORS middleware documentation: https://github.com/expressjs/cors#configuration-options

  • If you need to send the cookies cross-domain, you might need to add these to the cors configuration:
credentials: true,
allowedHeaders: ["Cookie", the rest of the headers]

2. (HACKY) In order for Vercel to allow CORS you should have an empty /dist folder, which is not produced by the build with Nest.js. To do so you can create a new dist folder with an empty file .gitkeep inside, so that GIT can detect it:

md dist
cd dist
touch .gitkeep

Commit and push this folder to git.

You may need to add to .gitignore to allow tracking this folder, as it might be excluded:

!backend/dist/.gitkeep

3. After deployment, test the response from the console:

curl --dump-header — -o /dev/null https://backend_api -H "Origin: https://frontend_app"

It should contain the CORS headers in the response:

access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
access-control-allow-origin: https://frontend_app

And you’re done!

--

--

Yosif Yosifov
Yosif Yosifov

Written by Yosif Yosifov

engineering lead, startup enthusiast, reader, climber

No responses yet