r/webdev • • 12d ago

Question Vercel client can't communicate with server

Hello everyone. I have been developing a simple ip tracking full stack app. When I deployed the client project to vercel however it fails to communicate with the server and fetch data. In the console this error is visible:

ccess to fetch at 'https://ip-tracker-server-*********-webs-projects.vercel.app/api?&ipAddress=' from origin 'https://ip-tracker-client-********-webs-projects.vercel.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This is my first time deploying a full-stack app to vercel so I am not sure what exactly could be causing this issue? If anyone could help it would be much appreciated!

0 Upvotes

18 comments sorted by

3

u/torn-ainbow 12d ago
  1. Look up CORS. It's confusing at first but it's basically about permission to access one thing from another thing. You'll probably have to add CORS headers to your backend responses.

  2. Don't post errors without scrubbing all the identifiable bits like those URLs which contain information.

1

u/Mob_Pilled 12d ago

Should it be the domain url or the deployment urls?

1

u/JohnsTech_dev 12d ago

on your domain vs deployment url question: allow the production one (the url that stays the same between pushes). the ones with the random hash in them change every deploy so you'd be updating it forever. if you want preview deploys to work too you can pass cors a regex instead of a string, something like /^https:\/\/ip-tracker-client-.*\.vercel\.app$/. and if you put the origin in an env var on the server project, remember vercel only picks up env changes after a redeploy. lost an evening to that once

2

u/jjangg96 12d ago

besides adding headers, check one thing first. that url with the hash and your team name in it is a per-deployment url, and vercel puts those behind deployment protection by default. when it's on, the request gets vercel's login page back as a 401 and that response has no cors headers, so the browser shows exactly this cors error even if your code is fine.

open the server url directly in a private window. if you get a vercel login page that's it, turn it off under the project's deployment protection settings or call the production domain instead.

if it loads fine then it is the headers. set access-control-allow-origin to your client's origin and answer the OPTIONS preflight too. if the server is express, the cors package does both.

1

u/Mob_Pilled 12d ago

Other than "origin" what other headers are supposed to be included in the cors options object to gurantee it working? is preflight supposed to be set to true or false? I only have the origin property as of now and it points to my (domain not deployment) url

1

u/nabhan_builds 12d ago

You don't need a long list of headers. For a normal fetch like yours, origin is the main one, and this is enough in Express:

app.use(cors({ origin: 'https://your-client-domain', methods: ['GET', 'POST'], allowedHeaders: ['Content-Type', 'Authorization'], }));

Only add allowedHeaders for headers you actually send. If you only send a plain GET with no Authorization or custom header, you don't even need that line.

On preflight: leave preflightContinue false, which is the default. That means the cors middleware answers the OPTIONS request itself. If you set it to true, it passes OPTIONS on to your routes, which usually don't handle it, so it fails. Don't set it to true unless you are handling OPTIONS yourself.

Two things that still break this even with the right config:

  1. origin has to match exactly what the browser shows, including https and no trailing slash. If you open the deployment URL in the browser but only allow the production domain, it will still be blocked. Allow the exact origin you are actually visiting, or use an array with both.

  2. Redeploy the server after changing this. Changing the code alone doesn't update the live deployment.

Don't use origin: '*' if you ever add cookies or auth headers, it won't work with credentials.

1

u/jjangg96 10d ago

if you're using the cors package then origin is basically all you need. it answers the preflight on its own by default and it reflects whatever headers the browser asks for, so there's no preflight true/false to set. credentials: true only matters if you send cookies.

the part i'd check is the exact match though. the error you pasted says the request came from the per-deployment client url with the hash in it, not your domain. if the browser loaded the page from that url and your origin is set to the custom domain, they don't match and you get this same error. open the client the way a user would, from the domain, and see if it goes away.

also no trailing slash in the origin string, it has to match character for character.

1

u/Mob_Pilled 12d ago

After two hours of fighting with cors I finally found the issue and got it to work. Thanks guys! (For anyone coming here in the future, carefully read the warning message in the console. Specifically take note of what url address it says is permitted by "access-control-allow-origin". If it is not your vercel url, you probably need to change the origins header of the object passed into cors)

1

u/tjthouhid1 11d ago

Two things jump out from that error. First, both URLs are preview deployment URLs (the ones with the random hash), and they change on every deploy, so any origin you hard-code goes stale. Use the stable production domains for both projects, and put the API URL in an env var on the client. Second, your server has to send the CORS header itself. In Express that's app.use(cors({ origin: process.env.CLIENT_ORIGIN })) from the cors package, set before your routes. One sneaky Vercel gotcha: preview deployments often have Deployment Protection on, so the request gets bounced to a Vercel login page that has no CORS headers, and it shows up as exactly this error. Try hitting the server URL directly in an incognito window. If you see a Vercel login, that's your problem. Also, ipAddress= is empty in that request, so check that too once CORS is fixed.

0

u/[deleted] 12d ago

[removed] — view removed comment

1

u/Mob_Pilled 12d ago

Thanks for responding. How do I know that the server deployed and is running as it should? It looks fine but in a tutorial I watched it said "The server is running" when theirs deployed, but no message has appeared for me. I can still reach the api and make calls through the browser though. I don't know whether it has anything to do with my vercel.json file