I have an express server that handles: 1 API route and rendering my initial index.html
to include bundle.js
holding my React/React-Router/Redux application.
As it stands, it is impossible to 404 on my web page as I have a catch all:
app.use(function (req, res) {
return res.render('index')
})
In order for react-router
's NoMatch
to work I need to send a 404 code.
My routes are as follows:
Express — /api/test/:x/:y
React Router — :x/
, :x/:y
What I am essentially trying to achieve is, if the user ever goes to a URL of: :x/:y/z/and/further
then return a 404, unless what they've gone to is /api/test/:x/:y
Questions:
- How can I match routes, excluding my API routes, preferably in a scalable way, returning appropriate status codes?
- For something so simple, is there significant overhead in setting this up on a subdomain? Would that even alleviate the issue? Would I face issues when the app grows?
Take a look at react-router server side rendering docs: https://github.com/reactjs/react-router/blob/master/docs/guides/ServerRendering.md
Solution:
match
function fromreact-router
. It should be written after middlewares that responsible for API routes.So, middleware should be similar to this:
If any routes change, you don't need to do something on express app, because you're using same code for frontend and backend.
You need to put your actual API routes above your catch-all so that they are picked up before it.
Basically, middlewares defined first take precedence over route complexity.
Once a response is sent to the client, Express will stop processing middleware unless an error is thrown or for some reason,
next
is manually called.You can define a simple error handler like so:
Sound like you could just use the order of routs to your advantage.
This way the request will try
/api/test
then/something/something
then if its/something/something/something-else
it will fail.the
router
inexpress
is amiddleware
so, the order is very important when you define your routes. In order to separate the API routes you can create a module to handle these and then createmiddlewares
to catch others routes including one for a 404 response. Don't forget put the api routes first. This is an example:And the api route module:
I managed to get my React app with React Router v4 working with an express server running liquid.js similar to handlebars the solution would work the same way for any other template engine.
In your React App.js make sure you have the React Router v4 installed and set up like this:
The above code will make sure that when the user navigates your React app and the routes are doing their job sending the user to a page they navigate, refresh or enter in the URLs manually.
In your express server app.js you want to define the main access root "/" to your react app "Do not use a wildcard * (asterisk) this will not work!" :
Then if you would have a 404 in your express it would redirect your user back to React to handle the 404s using React Router, this method is done using an express error handler:
I spent a decent time research to get it working if anybody thinks this should be improved or it might need more support in the error function please let me know.