React CORS error in netlify

Hi, I developed a react app locally with Coinmarketcap API. It was giving me CORS policy error locally too but I managed to handle that error by adding API’s endpoint to the package.json file with a proxy key.

When I deploy my app on netlify, that proxy thing didn’t work anymore. I tried to put heroku.app URL to the beginning of my API but it didn’t work as well. I don’t know back-end so how can I fix this problem?

Here is my source code: react-projects/4-cryptocurrency-marketcap at main · serdargokhan/react-projects · GitHub

Hi @serdargokhan

Welcome to the forums :netliconfetti:

Proxying to another site on Netlify is covered in this documentation.

You can create a _redirects file in the public directory of your repository, or add a netlify.toml file to the root of your repository.

If you have any issues or questions, don’t hesitate to reply.

Thanks for helping! But this documentation doesn’t explain it clearly to say :frowning: Yes, I will add netlify.toml but what inside of it?

As per the documentation, if using a _redirects files the format is

/api/*  https://api.example.com/:splat  200

The netlify.toml format is in the section below this:

[[redirects]]
  from = "/search"
  to = "https://api.mysearch.com"
  status = 200
 
 # These are optional
  force = true
  headers = {X-From = "Netlify"}

which also links to this documentation

[[redirects]]
  from = "/home"
  to = "https://pro-api.coinmarketcap.com"
  status = 200
  force = true

Just with this netlify.toml file everything will be okay? Can you explain “from” and “to” keys more please :slight_smile:

That looks ok. If you need to access other paths e.g. /home/something, /home/and/away then you would change it to

[[redirects]]
  from = "/home/*"
  to = "https://pro-api.coinmarketcap.com/:splat"
  status = 200
  force = true

so that /home/something would map to https://pro-api.coinmarketcap.com/something.

The from is the path on your site you will reference as demonstrated above, where the to is the location proxied to (see what they did there!? :slight_smile: )

Ouch I made it worse :grinning_face_with_smiling_eyes: Now netlify page says this:

{
    "statusCode": 404,
    "error": "Not Found",
    "message": "Not Found"
}

I have 3 pages in my app(home, coins, exchanges) so I did like this .

[[redirects]]
  from = "/*"
  to = "https://pro-api.coinmarketcap.com/:splat"
  status = 200
  force = true

also, another point is that I have multiple API calls in this app. In the “to” field should it change?

https://pro-api.coinmarketcap.com/v1/exchange/map?CMC_PRO_API_KEY=${API_KEY}&limit=20&sort=volume_24h

https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?CMC_PRO_API_KEY=${API_KEY}

Hi @serdargokhan,

Could you share the site name?

Hi,

this is my website: Crypto Marketcap (serdargokhan-crypto-marketcap.netlify.app)

But now I have reached my API limit for today so it might not work :frowning:

With this rule in place, this is what I see when directly viewing https://serdargokhan-crypto-marketcap.netlify.app/home.

This is because the rule is proxying everything to the coinmarketcapp site. With React and other SPAs, you need a rule as outlined here to point everything to the index.html in the project.

I see home is the main page of your site, so you do not want to have this route proxying to this other site. What you will want to do is configure an API route e.g.

[[redirects]]
  from = "/api/*"
  to = "https://pro-api.coinmarketcap.com/v1/:splat"
  status = 200
  force = true

This rule needs to go before the SPA catch-all rule otherwise it will never get triggered.

Then any call to pro-api.coinmarketcap.com (such as this one) get changed to this format:

`/api/cryptocurrency/listings/latest?CMC_PRO_API_KEY=${API_KEY}`

If CORS is in place, you will still need to add the relevant header values to both Netlify and Coin Market Cap.

I created _redirects file under public folder and I put this /* /index.html 200 into that file also, I did this

[[redirects]]
  from = "/api/*"
  to = "https://pro-api.coinmarketcap.com/v1/:splat"
  status = 200
  force = true

but still it does not work :frowning:

I see this in Developer Tools

Cross-Origin Request Blocked: The Same Origin Policy disallows reading 
the remote resource at
https://pro-api.coinmarketcap.com/v1/global-metrics/quotes/latest?CMC_PRO_API_KEY=undefined. 
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 401.

which means you are still trying to call the URL directly, not using the /api proxy you have configured e.g

// js/list/Token.js
const response = await fetch(`https://pro-api.coinmarketcap.com/v1/cryptocurrency/info?CMC_PRO_API_KEY=${API_KEY}&symbol=${coinNames}`);

Also note the CMC_PRO_API_KEY=undefined at the end. Have you set REACT_APP_API_KEY as an environment variable?

If this API key meant to remain private? If so, using this as you currently are will expose it in your front end. If you wish it to remain private, consider moving the calls to coinmarketcap into a serverless function.

I guess I have configured /api proxy successfully now for the home page. Because now CORS error is gone but it says Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

I set REACT_APP_API_KEY in .env file in my root folder. I know it does not keep it completely private still but for now it is okay for me. I will handle with it after I successfully publish the website :grinning_face_with_smiling_eyes:

Hi @serdargokhan,

You’ve still got the redirects incorrectly configured. As @coelmay said here:

The /api/* rule needs to be placed above the /* rule that you have.

My _redirects file under public folder is like this now:

/api/* /index.html 200
/*  /index.html  200

But I still get the same error : Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

The API idea of having the /api redirect is to proxy to coin market app, no back to index.html.

Try the following in the _redirects file

/api/*    https://pro-api.coinmarketcap.com/v1/:splat    200
/*        /index.html    200

Also note in js/list/Token.js you now have

const response = await fetch(`api/cryptocurrency/info?CMC_PRO_API_KEY=${API_KEY}&symbol=${coinNames}`);

This needs a leading / i.e

const response = await fetch(`/api/cryptocurrency/info?CMC_PRO_API_KEY=${API_KEY}&symbol=${coinNames}`);

as do any other instances through your app.

Okay, finally it is kind of working I guess. Now I get 401 error code with my API call which is unauthorized. In my local server, it was working with .env file and API key inside of it. What is the problem now, why does it not read my .env file?

Am I to assume you are running Netlify CLI locally for the redirects to function properly? If so, instead of accessing the environments variables like

API_KEY

you need

process.env.API_KEY

Also note that React App requires keys accessible on the frontend to have the prefix REACT_APP_

Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have NODE_ENV defined for you, and any other environment variables starting with REACT_APP_ .

So for your API_KEY you would set it as

REACT_APP_API_KEY=whatever-the-value-is

and access it via

process.env.REACT_APP_API_KEY

In my .env file I have REACT_APP_API_KEY = my-api-key and inside of my react app I use it like this

const API_KEY = process.env.REACT_APP_API_KEY; and in my API call it is like this

const response = await fetch(/api/exchange/map?CMC_PRO_API_KEY=${API_KEY}&limit=20&sort=volume_24h);

Ok, that seems perfectly fine. Without seeing/testing the code, I can’t say why it isn’t working any more.