When we deploy a simple nodejs express app to vercel, we are most likely to encounter cors issues most of the times. Personally, I often get cors errors each time I deploy to vercel.
Till yesterday, I was getting intimidated by these errors very much. Even, I have spent more than 2 days in resolving this error. The app works on my local machine but as soon I deploy it on vercel, it gets cors issue.
There are multiple solutions of this problem. Some of you will say using CORS node js module will work fine. But it does not. It tackle some of the errors but not all and not every time.
The more effective solution is giving vercel the headache of your CORS issues.
So, This is the folder structure of most of the simple apps.
We have a root folder in which we have our index.js, package.json, package-lock.json.
Our index.json has all our express server code.
Now, to deploy it on vercel, we make vercel.json file in the root folder. Generally, this is the vercel.json code we write for our routes and build. This works most of the time and almost everyone uses this copy-paste template to deploy on vercel.
{
"version": 2,
"builds": [
{
"src": "index.js",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/"
}
]
}
The problem I got in my projects was, even though I was using cors module in my code but then to I was having cors error sometimes. I went to vercel documentation and found out that we can fix this error using vercel.json. I tried solutions given on vercel (copied and pasted the code) but it was failing the checks of deployment. The solutions given on vercel are for specific cases. The solutions in the vercel documentation about vercel.json properties did not mention where or with which property we dont have to use these headers or properties. Encountering this problem took me more than 2 days to understand whats wrong I was doing. I tried searching on stackoverflow, reddit and other discussion portals and communities but didn’t found a good and simple solution. Now, when I have handled the issue I want to share this post so that developers dont have to go here and there for resolving and waste their time trying and handling errors.
Here, is the new updated vercel.json file handling cors issues.
{
"version": 2,
"builds": [
{
"src": "*.js",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/",
"methods": ["GET","POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
}
}
]
}
This JSON code can save you lots and lots of time when deploying your code on vercel. The methods and header properties ensure that vercl handle all the cors issues.
You can adjust routes and builds according to your file structure.
Feel free to ask any questions and leave your feedback. Hope you find this post helpful. I will be regularly posting the problems I face in my development journey, that dont have a staright solution available on internet and their solutions I get from my experiments.
Thank you so much for giving time and reading my post.
Kartikey Jaiswal
Top comments (7)
I'll say this "works" only because you're saying "*" which means "any domain can send me requests"
That makes this is a "bad" or "not secure" setup.
Unless you want any website on the planet to hit your api directly.
To properly setup CORS on express you should be defining which domains are allowed to send requests to your server. In your case that means replacing that * with
"virmigo.vercel.app" so only that domain can send requests to your backend.
Of course if you're running a local copy or have other subdomains you're using, you need to add those as well comma-separated or they'll get CORS errors.
You should also restrict the METHODS you actually need. Chances are you're only using GET, POST, and OPTIONS [is necessary for CORS verification by the browser]
You might be using PUT if someone taught you to, but PATCH and DELETE almost no one uses. Ideally we'd all just freaking use POST all the time and just get on with our lives, but some disagree and pretend the server cares about what we want, it really doesn't.
I hope this helps you and anyone else who came across this to understand CORS a bit better.
And also make sure you use two version of your vercel url in your backend cors access, for example in nest js main.ts file
app.enableCors({
origin: [
'http://localhost:5173',
'https://www.yourdomain.com',
'https://yourdomain.com',
],
credentials: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
});
This worked but now it gives gateway timeout error.
Checked the error. it is due to vercel limit to request for hobby plan which is 10 seconds. This happens when you request from example: mongodb from your server which takes time. Thus, either buy pro plan or dont use/request other api.
It works fine with resend or nodemailer and such. Vercel allows that for free tier.
it's not working
this does not work
For me it's working, thanks. I was struggling with it from 2 days.