Blog » How to setup routing for Not Found on both sides with React-Router and Express

How to setup routing for Not Found on both sides with React-Router and Express

2018-03 |

This content is only available in english

How to setup routing for Not Found on both sides with React-Router and Express

When building web applications in React, I usually choose Express to be my server, and more often than not I use React-Router to manage redirections and changes in history. Not without a reason - both are among the most popular choices in their respective fields nowadays; both are simple and elegant in every day work. However, I had some tough moments with both of them when it came up to setting all unrecognized routing to "Not Found" page, and this piece came as a result of them.

My goal was to have Not Found page as part of my Single Page Application, not some separate and entirely different piece of code, which I can't reliably control, and which may stand out noticeably from my sleek user interface. It required me to shift most of the decision making process when it comes to routing from my back-end to my front-end. Therefore, I came to realization, that I will now use Express to serve static content only, and this is common and well documented use case. Quickly I came up with simple configuration, that always serves static index.html file.

const fs = require('fs');
const path = require('path');
const express = require('express');

const app = express();

app.use(express.static(path.join(__dirname, '../dist/index.html')));

app.use((request, response) => {
  fs.readFile(indexPath, (error, file) => {
    if (error) {
      response.status(404).send(error.toString());
    } else {
      response.status(200).send(file.toString());
    }
  });
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

Then, I moved to React-Router. Basic component of this library is Route, with property path, which describes chunk of URL, corresponding to the view to be displayed. React-Router documentation states, that "routes without a path always match", and that was exactly what I needed. Having Route without path, pointing to Not Found view, I only needed to redirect some other routes to meaningful views that I had consciously created, and everything else is covered.

However, in React-Router, routes on their own render when they match URL inclusively. Not Found view stated as a Route without path would render unconditionally and irrespectively of the URL. Switch, also coming from React-Router, solved me this issue. In Switch, routes render when they match the URL exclusively, which means that always up to one Route will be rendered, and always it will be the first one that matches the URL. I put my Not Found Route at the end of Switch, and I was good to leave the office. Job well done.

import * as React from 'react';
import { Route, Switch } from 'react-router-dom';

import Home from 'components/Home';
import About from 'components/About';
import NotFound from 'components/NotFound';

export const App = (): JSX.Element => {
  return (
    <Switch>
      <Route exact="{true}" path="/" component="{Home}/">
      <Route path="/about" component="{About}/">
      <Route component="{NotFound}"/>
    </Route></Route></Switch>
  );
};

export default App;

Other blog posts

Moving from Sass to Styled Components (with snapshot tests)

2018-08 |

This content is only available in english

Moving from Sass to Styled Components (with snapshot tests)

Who doesn't like to constantly rework perfectly fine stuff into something new and fancy just because it's trendy now? Well, probably pretty much every single JS developer, most certainly everyone who works with this language long enough to experience at least a glimpse of famous "JS fatigue" feeling (so approximately a few weeks). However, I created this blog as a playground to try out new libraries and frameworks, and since I'm learning Styled Components for my professional work at the moment, even though Sass-based styling worked perfectly for my needs, I reimplemented all of it into this controversial CSS-in-JS. And I'm still sane!

Continue reading

Webpack 4 config explained (with example)

2018-04 |

This content is only available in english

Webpack 4 config explained (with example)

Using a skeleton for your application prepared by someone else comes with great benefit of a lot of time saved, but also with huge cost of a lot of knowledge not obtained. Sometimes you'll manage to complete your assignment just fine with some predefined boilerplate, without too much need for deep investigation of it's nooks and crannies. Other times, you'll end up in a position, where you reverse engineer it in order to introduce some major change, or just give up and start from scratch with your own thing. I wouldn't like you to give up on my application skeleton. Thus, I'll describe some of it's shenanigans in it's documentation. Today, I'm explaining build process.

Continue reading

Hard to imagine, but it's over 1 year since I created this blog, and up until recently, it always had static head tags. Title always being the same, for example, wasn't that much of an issue to me, but social meta tags never related to the content of the post I'm sharing on Twitter, that was not cool (it's also not cool when it comes to SEO, but it's not that much of my concern right now). I finally had to tackle it. Here's a simple way to do it that I've found.

Continue reading

How to set up tooling around your open source project

2019-11 |

This content is only available in english

How to set up tooling around your open source project

Lately in my project we had very particular need for specific validation of content of JavaScript bundle produced by Webpack. In the process of extensive research we have not found any existing tool to serve this purpose. Therefore, I've created Webpack Bundle Content Validator, which is a Webpack plugin and a CLI tool for Webpack bundle content validation. More importantly, I made it open source. Surprisingly, simply publishing it to NPM wasn't enough - I decided to set up continuous integration, automated unit tests code coverage calculation, automated check for vulnerabilities and a few other things, in order to make it legitimate and reliable package. In this post I'm describing those steps in details.

Continue reading

My first MobX store

2018-07 |

This content is only available in english

My first MobX store

My dad wants to read my blog. The only issue is that he doesn't speak English very well. It's communicative, but it's not quite enough to understand intricate, sophisticated Shakespearean language, I am decorating my posts with. Worry not, father, as I've found the solution: language versions. I am currently working on adaptations of my posts in Polish language. In the meantime, I'm also adapting my codebase to be able to recognize and properly handle language parameter. And for that purpose, for the first time, I decided to use MobX.

Continue reading