External Backend Service, Redirect Help

Hello Netlify enthusiasts! I’ve come across this difficulty with several Netlify apps in the past and am hoping to learn the best practice once and for all.

I commonly have to interact with a completely external backend service that I do no control in any way. My frontend infrastructure is typically a very normal create-react-app service that uses react-router.

In local development, I cannot hit this API directly:

fetch(https://externalservice.com/users/)

Because it will cause a CORS issue fetching from localhost:3000.

I solve this by putting a proxy in my package.json, a create-react-app feature:

{
   "proxy": "https://externalservice.com"
}

At which point, relative frontend queries work expectedly, like:

fetch(/users)

During local development, my apps work perfectly now. However, when I got to deploy the app is where my problems begin. Of course, now the relative fetch requests do not work, because the proxy is only for local development.

I go to my netlify.toml file and add:

[[redirects]]
  from = "/*"
  to = "https://externalservice.com"

Which nearly works, except that now when my React-Router does not appear to work.

https://myapp.com/homepage

Will always return route not found. Searching online shows me that this is because you need something like this change to your YAML file in order to let client side routing take effect:

[[redirects]]
  from = "/*"
  to = "/index.html"

But I cannot make this change since the from is the same.

Any and all help or guidance is greatly appreciated, thanks :pray:

Welcome to the forums @trevorwhealy

Excellent first post!

Correct, to make React Router work you need

[[redirects]]
  from = "/*"
  to = "/index.html"

in a netlify.toml or the following in a _redirects file

/*    /index.html    200

This rewrite is a must.

Rules are processed top to bottom and _redirects rules are processed first then netlify.toml rules. Better to choose one file for redirects only.

To proxy to another service the convention is to have a rewrite

[[redirects]]
  from = "/api/*"
  to = "https://api.somewhere.com/v1/:splat"
  status = 200

Rather than using

fetch("https://api.somewhere.com/v1/users", ...)
// or
fetch("/users", ...)

as previously, all calls go via the /api e.g

fetch("/api/users", ...)
// or
fetch("/api/user/123456", ...)

This rule (and any other rules) must go above the SPA catch-all rule otherwise everything gets routed back to the SPA.

[[redirects]]
  from = "/api/*"
  to = "https://api.somewhere.com/v1/:splat"
  status = 200

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

or if you wanted to use a _redirects

/api/*   https://api.somewhere.com/v1/:splat    200
/*    /index.html    200

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

1 Like