17

On the server an API only path has been set under /api.

When calling this path on the client-side, react-router takes over and responds with:

browser.js:49 Warning: [react-router] Location "/api/my_request" did not match any routes

How can we tell react-router to bypass this and just send the request out to the server?

Update:

This is how the request is being sent:

const sock = new SockJS('http://localhost:3030/api')

sock.onopen = () => {
  console.log('open')
}
sock.onmessage = (e) => {
  console.log('message', e.data)
}
sock.onclose = () => {
  console.log('close')
}

sock.send('test')
BAR
  • 15,909
  • 27
  • 97
  • 185
  • That's something you do on the server. If `/api` is matched on the server that is sending you data, then it won't serve your html page that has your React application – azium Jun 27 '16 at 20:38
  • @azium Thing is the request can never be matched on the server because react-router is first in line to match on the client. – BAR Jun 27 '16 at 20:39
  • 1
    I'm not quite following you, what kind of request are you trying to make? Are you trying to load another html page or what? React router will only attempt to change the url through `history.push` so regular links or ajax requests won't trigger react-router whatsoever – azium Jun 27 '16 at 20:46
  • @azium Response would be a JSON object for my case, but that doesn't really matter. The idea is getting react-router to pass through the URL request rather than handle it itself. – BAR Jun 27 '16 at 20:48
  • So there are two scenarios here: User copies and pastes `yourserver.com/api/some_json` and react-router is never called because your server didn't respond with an html/javascript bundle just JSON. or scenario 2) you're already on the client app and you make a normal get request `ajax.get('/api/some_json')` which react router can't possibly intercept – azium Jun 27 '16 at 21:01
  • @azium I didn't think the request lib made a difference, but since you mention it I updated the post to show how I am using sockjs. – BAR Jun 27 '16 at 21:04
  • Where / how are you making a request to `api/my_request` ? The thing that actually triggers the react-router incorrect match warning? If you're saying that calling `new Sock()` is throwing this error, something is highly suspect. – azium Jun 27 '16 at 21:10
  • @azium `sock.send('test')` – BAR Jun 27 '16 at 21:11

2 Answers2

6

Here is how I bypass React Router for my API routes with React Router 4.

I had to remember that React Router is in a React component. We can use JavaScript within it and we can test the URL.

In this case, I check for /api/ in the pathname of the URL. If it exists, then I do nothing and skip React Router entirely. Else, it has a route that does not begin with /api/ and I let React Router handle it.

Here is my App.js file in my client folder:

import React from 'react'
import Home from './components/Home'
import AnotherComponent from './components/AnotherComponent'
import FourOhFour from './components/FourOhFour'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'

export default function App() {
   const api_regex = /^\/api\/.*/
   // if using "/api/" in the pathname, don't use React Router
   if (api_regex.test(window.location.pathname)) {
      return <div /> // must return at least an empty div
   } else {
      // use React Router
      return (
         <Router>
            <div className="App">
               <Switch>
                  <Route exact path="/" component={Home} />
                  <Route exact path="/another-link" component={AnotherComponent} />
                  <Route component={FourOhFour} />
               </Switch>
            </div>
         </Router>
      )
   }
}
149203
  • 186
  • 3
  • 10
  • can you show how you have set route in the backend in node.js app.js to serve react app and also the /api/ ? – vikrant Aug 03 '20 at 00:08
0

Hi i had the same issue and this was my solution, this is my DefaultController the entry point of the React app.

class DefaultController extends AbstractController
{
   /**
   * @Route("/{reactRouting}", name="home", requirements={"reactRouting"="^(?!api).+"}, defaults={"reactRouting": null})
   */
  public function index()
  {
    return $this->render('default/index.html.twig', [
        'controller_name' => 'DefaultController',
    ]);
  }
}

Notice that the "requirements" defines the regex for bypass /api path, and with this react router will ignore this route and the request will be handle by the server. I hope this works for you. Regards!