Use react-router-dom for client side routing

Create a React app using the create-react-app command. For details, you can check out my other post to get started.

React-router-dom is a package used for Client side routing and you can install it from npm. Since React lets you create Single Page Applications (SPA), you need to use react-router to navigate between different components, changing the browser URL, modifying the browser history, and keeping the UI state in sync. SPA only modifies parts of a page instead of loading entire new pages from a Server.

react-router is the core package for routing, however for web you can use react-router-dom as shown in this demo.

The index.js file will use BrowserRouter from the API which uses the HTML5 History API e.g. http://abc/route/subroute

Our App component will be wrapped inside the BrowserRouter. The Router component can have only one child element.

Code sample below for index.js file:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./components/App";
import * as serviceWorker from "./serviceWorker";
import { BrowserRouter as Router } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById("root")
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

App.js component code:

import React from "react";
import { Route, Switch } from "react-router-dom";
import HomePage from "./home/HomePage";
import AboutPage from "./about/AboutPage";
import Header from "./common/Header";
import PageNotFound from "./PageNotFound";
import CoursesPage from "./courses/CoursesPage";

function App() {
  return (
    <div className="container-fluid">
      <Header />
      <Switch>
        <Route exact path="/" component={HomePage} />
        <Route path="/courses" component={CoursesPage} />
        <Route path="/about" component={AboutPage} />
        <Route component={PageNotFound} />
      </Switch>
    </div>
  );
}

export default App;

Use the Switch component to match the first route that matches the location for rendering and does not look further.
exact property is used to match the URL path exactly. This will match the Home page for “/” path.

What happens when no route matches? We need to handle this scenario with a PageNotfound error page. Path attribute is not used for this Route but only the Component is required.

Link component is used to create links in your application. NavLink is used to add the style attributes to the active routes.

Code for Header section:

import React from "react";
import { NavLink } from "react-router-dom";

const Header = () => {
  const activeStyle = { color: "#F15B2A" };

  return (
    <nav>
      <NavLink to="/" activeStyle={activeStyle} exact>
        Home
      </NavLink>
      {" | "}
      <NavLink to="/courses" activeStyle={activeStyle}>
        Courses
      </NavLink>
      {" | "}
      <NavLink to="/about" activeStyle={activeStyle}>
        About
      </NavLink>
    </nav>
  );
};

export default Header;

You can find the complete code sample here in my github profile under the react-router-dom-demo branch.

Handle client side routes with IIS on Page refresh React App

When trying to handle Client side routing for your React App hosted on IIS say using react-router-dom, you might need to handle situations where users access specific sections of your App like http://testapp/courses. Users might even save these URLs in their favorites and try to access them later.

This problem is not known while debugging the App in localhost until you host the App on an IIS Server. Since your React App is a Single Page Application (SPA), the Server is unaware of any static files like courses and will give 404 error. To solve this, send all your requests back to IIS with URL rewrite to the index.html static file and let the React App handle the routing.

First install the URL Rewrite module on the IIS Server. Then create a web.config file for your App or create a new one with code as shown below:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
		<rewrite>
		  <rules>
			<rule name="ReactRouter Routes" stopProcessing="true">
			  <match url=".*" />
			  <conditions logicalGrouping="MatchAll">
				<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
			  </conditions>
			  <action type="Rewrite" url="index.html" />
			</rule>

		  </rules>
		</rewrite>
    </system.webServer>
</configuration>

This should work well for your App when the user tries to access a Client side route and refresh the page or when trying to access the route later.