How to add routes to a React app

In this example we’ll just be looking at static routes, I’ll create a more detailed post including how to implement dynamically generated routes in the near future.

Creating a basic React project

If you already have a project up and running please ignore this section and skip ahead.

  1. Install Node.js
  2. Open whichever command-line tool you use and enter the following command:
    node -v
  3. This will return a version number, confirming you have node installed.
  4. Staying in the command line, navigate to the folder you want to create the React app, eg:
    cd c:/myProjects/
  5. Create a new folder if required:
    mkdir react-routes
  6. Then CD into the new folder:
    cd react-routes
  7. Create the new React app using the following command:
    npx create-react-app my-new-app
  8. This will create the new react app called ‘my-new-app’
  9. Once the setup script had finished, CD into the ‘my-new-app’ directory and run:
    npm start
  10. This should automatically open your browser, if not then navigate to http://localhost:3000

All done!! you should see the default react start page:

Let’s create some new pages

Now that we have a basic React app up and running, we need to create some basic pages.

In /src/ create a new JS file called ‘About.js’, and add a very basic function which returns some JSX:

import React from 'react';

function About() {
  return (
    <div>
      <h1>About</h1>
    </div>
  );
}

export default About;

Do the same again, creating another 2 pages Contact.js and Home.js:

import React from 'react';

function Contact() {
  return (
    <div>
      <h1>Contact</h1>
    </div>
  );
}

export default Contact;
import React from 'react';

function Home() {
  return (
    <div>
      <h1>Home</h1>
    </div>
  );
}

export default Home;

Import everything we need into App.js

Open App.js and import the 3 pages we have created:

import Home from './Home';
import About from './About';
import Contact from './Contact';

Then in the command line (might be an idea to stop the server with CTRL + C for this bit) run the command:

npm install --save react-router-dom

This will install the react-route-dom package, we’ll need a few bits from this! Import BrowserRouter, Switch, Route and Link from this new package:

import Home from './Home';
import About from './About';
import Contact from './Contact';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';

Update the App function

Now we have imported everything we need into App.js, lets dive into the App function.

Open App.js and wrap the JSX in a <Router> tag:

function App() {
  return (
    <Router>
      <div>
        
      </div>
    </Router>
  );
}

Create a new folder called ‘Components’ in /src/ (/src/Components). In the new folder create a file called Nav.js, this will be our basic navigation. Import the Link helper from the ‘react-router-dom’ package and define a ‘to’ attribute for each of the pages we want to specify:

import React from 'react';
import { Link } from 'react-router-dom';

function Nav() {
  return (
    <nav>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/contact">Contact</Link>
        </li>
      </ul>
    </nav>
  );
}

export default Nav;

Import the Nav component into our main App.js file and add it to the JSX:

import React from 'react';
import Home from './Home';
import About from './About';
import Contact from './Contact';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Nav from './Components/Nav';

function App() {
  return (
    <Router>
      <Nav />
    </Router>
  );
}

export default App;

Let’s pause for a moment and take a look at our app in the browser we’ll see the list of basic links:

And if we click on each of the links, the relative path in the address bar updates to match what we specified in our <Nav /> component:

Wiring up the components

The last thing we need to do it tell React what the display when each of the paths is visited, underneath the Nav component in App.js add a Route component helper with the path and the component to display when that path is visited:

function App() {
  return (
    <Router>
      <Nav />
      <Route path='/' component={Home} />
      <Route path="/about" component={About} />
      <Route path="/contact" component={Contact} />
    </Router>
  );
}

If we look at the app in the browser it looks good (at first):

The title “Home” is the JSX from the Home.js file we created earlier.

BUT!!!…. If we click on any of the other links something quite unexpected happens:

Clicking on the ‘about’ link returns the content for both Home (“/”) and About (“/about”), this is expected but why does this happen?.. It’s related to how URL matching works within Router, when we visit the URL “/about” 2 paths are matched, the first is the forward slash “/” and then the path name “about” so React will render both of these component views.

There are 2 parts to fix this issue:

  1. We need to wrap the Routes in a Switch helper:
function App() {
  return (
    <Router>
      <Nav />
      <Switch>
        <Route path='/' component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Switch>
    </Router>
  );
}

Switch will only match 1 path in a single request. Which causes a new problem, when you visit “/about” Router will still match the initial “/” of the request and then matching stops, to regardless of which link you click you will always see the component we defined for the root path.

2. To fix this second issue, we need to tell the Router to only match the root path when the match is ‘exact’:

function App() {
  return (
    <Router>
      <Nav />
      <Switch>
        <Route exact path='/' component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Switch>
    </Router>
  );
}

That’s it! if you view the app in the browser you’ll be able to navigate between component views using links.