Build a Secure SPA with React Routing

When building an SPA (single page application) with React, routing is one of the fundamental processes a developer must handle. React routing is the process of building routes, determining the content at the route, and securing it under authentication and authorization. There are many tools available to manage and secure your routes in React. The most commonly used one is react-router. However, many developers are not in a situation where they can use the react-router library. Because of this, they may need to use Reach Router, Wouter, or maybe even no router at all.

This tutorial will show you how to quickly build a secure SPA using React, Okta, and Wouter. Okta easily enables you to manage access to your SPAs (or any application for that matter). By using the @okta/okta-react library you can quickly build secure applications with React. At the time of writing this article, reach-router does not support React version 17+.

Prerequisites:

Table of Contents

Create an Okta OIDC application

Before you begin, you’ll need a free Okta developer account. Install the Okta CLI and run okta register to sign up for a new account. If you already have an account, run okta login. Then, run okta apps create. Select the default app name, or change it as you see fit. Choose Single-Page App and press Enter.

Use http://localhost:3000/callback for the Redirect URI and set the Logout Redirect URI to http://localhost:3000.

The Okta CLI will create an OIDC Single-Page App in your Okta Org. It will add the redirect URIs you specified and grant access to the Everyone group. It will also add a trusted origin for http://localhost:3000. You will see output like the following when it’s finished:

Okta application configuration:
Issuer:    https://dev-133337.okta.com/oauth2/default
Client ID: 0oab8eb55Kb9jdMIr5d6

NOTE: You can also use the Okta Admin Console to create your app. See Create a React App for more information.

Once Okta is done processing your request it will return an Issuer and a Client ID. Make sure you note these, as you will need them in your application.

Create a React application with routing

Next, open your favorite IDE (I use Visual Studio Code) and use the task runner npx create-react-app react-routing-demo to scaffold your React project. You’ll be prompted to install create-react-app. Type y to approve.

This process takes a minute, so grab a cup of coffee or tea if you prefer. The task runner does a great job of getting your application started quickly, but you will need to add and edit a few of the files.

Before you begin, you will need to install some packages.

First, of course, wouter.

cd react-routing-demo
npm i wouter@2.7.5

You will use Bootstrap along with the react-bootstrap library to style your app.

npm i bootstrap@5.1.3
npm i react-bootstrap@1.6.4

Next, you will get dotenv as a way of storing your sensitive Okta information.

npm i dotenv@10.0.0

Finally, you will add the Okta React SDK to your project.

npm i @okta/okta-react@6.2.0 @okta/okta-auth-js@5.6.0

With these dependencies installed, you can begin to create your app. First, add a new file called .env to the root of your project, and add the following items. Note here that the REACT_APP_OKTA_ISSUER should match the issuer from the Okta CLI.

REACT_APP_OKTA_CLIENTID={yourClientId}
REACT_APP_OKTA_APP_BASE_URL=http://localhost:3000
REACT_APP_OKTA_ISSUER=https://{yourOktaDomain}/oauth2/default
</code></pre>

<p>Next, add a folder for <code class="language-plaintext highlighter-rouge">Components</code> and one for <code class="language-plaintext highlighter-rouge">Pages</code>.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>src/Components
<span class="nb">mkdir </span>src/Pages
</code></pre></div></div>

<p>In <code class="language-plaintext highlighter-rouge">Components</code> add a new file for <code class="language-plaintext highlighter-rouge">Header.jsx</code> and add the following code.</p>

<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">React</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Navbar</span><span class="p">,</span> <span class="nx">Nav</span><span class="p">,</span> <span class="nx">Form</span><span class="p">,</span> <span class="nx">Button</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-bootstrap</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">Header</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">authState</span><span class="p">,</span> <span class="nx">oktaAuth</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">authState</span><span class="p">?.</span><span class="nx">isPending</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>Loading...<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;;</span>
  <span class="p">}</span>

  <span class="kd">const</span> <span class="nx">button</span> <span class="o">=</span> <span class="nx">authState</span><span class="p">?.</span><span class="nx">isAuthenticated</span> <span class="p">?</span> <span class="p">(</span>
    <span class="p">&lt;</span><span class="nc">Button</span>
      <span class="na">variant</span><span class="p">=</span><span class="s">"secondary"</span>
      <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="nx">oktaAuth</span><span class="p">.</span><span class="nx">signOut</span><span class="p">(</span><span class="dl">"</span><span class="s2">/</span><span class="dl">"</span><span class="p">);</span>
      <span class="p">}</span><span class="si">}</span>
    <span class="p">&gt;</span>
      Logout
    <span class="p">&lt;/</span><span class="nc">Button</span><span class="p">&gt;</span>
  <span class="p">)</span> <span class="p">:</span> <span class="p">(</span>
    <span class="p">&lt;</span><span class="nc">Button</span>
      <span class="na">variant</span><span class="p">=</span><span class="s">"secondary"</span>
      <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="nx">oktaAuth</span><span class="p">.</span><span class="nx">signInWithRedirect</span><span class="p">();</span>
      <span class="p">}</span><span class="si">}</span>
    <span class="p">&gt;</span>
      Login
    <span class="p">&lt;/</span><span class="nc">Button</span><span class="p">&gt;</span>
  <span class="p">);</span>

  <span class="k">return</span> <span class="p">(</span>
    <span class="p">&lt;</span><span class="nc">Navbar</span> <span class="na">bg</span><span class="p">=</span><span class="s">"light"</span> <span class="na">expand</span><span class="p">=</span><span class="s">"lg"</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nc">Navbar</span><span class="p">.</span><span class="nc">Brand</span> <span class="na">href</span><span class="p">=</span><span class="s">"/"</span><span class="p">&gt;</span>React Routing<span class="p">&lt;/</span><span class="nc">Navbar</span><span class="p">.</span><span class="nc">Brand</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nc">Navbar</span><span class="p">.</span><span class="nc">Toggle</span> <span class="na">aria</span><span class="err">-</span><span class="na">controls</span><span class="p">=</span><span class="s">"basic-navbar-nav"</span> <span class="p">/&gt;</span>
      <span class="p">&lt;</span><span class="nc">Navbar</span><span class="p">.</span><span class="nc">Collapse</span> <span class="na">id</span><span class="p">=</span><span class="s">"basic-navbar-nav"</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nc">Nav</span> <span class="na">className</span><span class="p">=</span><span class="s">"mr-auto"</span><span class="p">&gt;&lt;/</span><span class="nc">Nav</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nc">Form</span> <span class="na">inline</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">button</span><span class="si">}</span><span class="p">&lt;/</span><span class="nc">Form</span><span class="p">&gt;</span>
      <span class="p">&lt;/</span><span class="nc">Navbar</span><span class="p">.</span><span class="nc">Collapse</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nc">Navbar</span><span class="p">&gt;</span>
  <span class="p">);</span>
<span class="p">};</span>
<span class="k">export</span> <span class="k">default</span> <span class="nx">Header</span><span class="p">;</span>
</code></pre></div></div>

<p>This component displays a login button for your users. This button turns into a logout button once the user authenticates. The component also provides a place to access the <code class="language-plaintext highlighter-rouge">Profile</code> page you will create.</p>

<p>Add <code class="language-plaintext highlighter-rouge">Profile.jsx</code> to the <code class="language-plaintext highlighter-rouge">Pages</code> folder. The code for this file is as follows.</p>

<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">useEffect</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Container</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-bootstrap</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="p">{</span> <span class="nx">useOktaAuth</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@okta/okta-react</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="nx">Header</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">../Components/Header</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">Profile</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="p">{</span> <span class="nx">authState</span><span class="p">,</span> <span class="nx">oktaAuth</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">useOktaAuth</span><span class="p">();</span>

  <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">async</span> <span class="kd">function</span> <span class="nx">authenticate</span><span class="p">()</span> <span class="p">{</span>
      <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">authState</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>

      <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">authState</span><span class="p">.</span><span class="nx">isAuthenticated</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">await</span> <span class="nx">oktaAuth</span><span class="p">.</span><span class="nx">signInWithRedirect</span><span class="p">();</span>
      <span class="p">}</span>
    <span class="p">}</span>

    <span class="nx">authenticate</span><span class="p">();</span>
  <span class="p">},</span> <span class="p">[</span><span class="nx">authState</span><span class="p">,</span> <span class="nx">oktaAuth</span><span class="p">]);</span>

  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">authState</span><span class="p">?.</span><span class="nx">isAuthenticated</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(</span>
      <span class="p">&lt;</span><span class="nc">Container</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Please wait while we sign you in<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
      <span class="p">&lt;/</span><span class="nc">Container</span><span class="p">&gt;</span>
    <span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(</span>
      <span class="p">&lt;</span><span class="nc">Container</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nc">Header</span> <span class="na">authState</span><span class="p">=</span><span class="si">{</span><span class="nx">authState</span><span class="si">}</span> <span class="na">oktaAuth</span><span class="p">=</span><span class="si">{</span><span class="nx">oktaAuth</span><span class="si">}</span><span class="p">&gt;&lt;/</span><span class="nc">Header</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">h4</span><span class="p">&gt;</span>Your profile page<span class="p">&lt;/</span><span class="nt">h4</span><span class="p">&gt;</span>

        <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Welcome to your profile page <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
      <span class="p">&lt;/</span><span class="nc">Container</span><span class="p">&gt;</span>
    <span class="p">);</span>
  <span class="p">}</span>
<span class="p">};</span>

<span class="k">export</span> <span class="k">default</span> <span class="nx">Profile</span><span class="p">;</span>
</code></pre></div></div>

<p>This page leverages the <code class="language-plaintext highlighter-rouge">useOktaAuth</code> hook to determine if the user is logged in. If the user is not logged in, then you will prompt them to log in with Okta. Otherwise, you will display a brief profile page.</p>

<p>Finally, add <code class="language-plaintext highlighter-rouge">Home.jsx</code> to the <code class="language-plaintext highlighter-rouge">Pages</code> folder with the following code.</p>

<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">React</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Link</span><span class="p">,</span> <span class="nx">Redirect</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">wouter</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="nx">Header</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">../Components/Header</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="p">{</span> <span class="nx">Container</span><span class="p">,</span> <span class="nx">Row</span><span class="p">,</span> <span class="nx">Col</span><span class="p">,</span> <span class="nx">Card</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-bootstrap</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">useOktaAuth</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@okta/okta-react</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">Home</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="p">{</span> <span class="nx">authState</span><span class="p">,</span> <span class="nx">oktaAuth</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">useOktaAuth</span><span class="p">();</span>

  <span class="k">return</span> <span class="nx">authState</span><span class="p">?.</span><span class="nx">isAuthenticated</span> <span class="p">?</span> <span class="p">(</span>
    <span class="p">&lt;</span><span class="nc">Redirect</span> <span class="na">to</span><span class="p">=</span><span class="s">"/Profile"</span> <span class="p">/&gt;</span>
  <span class="p">)</span> <span class="p">:</span> <span class="p">(</span>
    <span class="p">&lt;</span><span class="nc">Container</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nc">Header</span> <span class="na">authState</span><span class="p">=</span><span class="si">{</span><span class="nx">authState</span><span class="si">}</span> <span class="na">oktaAuth</span><span class="p">=</span><span class="si">{</span><span class="nx">oktaAuth</span><span class="si">}</span><span class="p">&gt;&lt;/</span><span class="nc">Header</span><span class="p">&gt;</span>

      <span class="p">&lt;</span><span class="nc">Row</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nc">Col</span> <span class="na">sm</span><span class="p">=</span><span class="si">{</span><span class="mi">12</span><span class="si">}</span> <span class="na">className</span><span class="p">=</span><span class="s">"text-center"</span><span class="p">&gt;</span>
          <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>React routing Demo<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>

          <span class="p">&lt;</span><span class="nt">h5</span><span class="p">&gt;</span>
            A <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="p">=</span><span class="s">"https://reactjs.org/"</span><span class="p">&gt;</span>React<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> Demo using<span class="si">{</span><span class="dl">"</span><span class="s2"> </span><span class="dl">"</span><span class="si">}</span>
            <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="p">=</span><span class="s">"https://github.com/molefrog/wouter"</span><span class="p">&gt;</span>Wouter<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> Secured by<span class="si">{</span><span class="dl">"</span><span class="s2"> </span><span class="dl">"</span><span class="si">}</span>
            <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="p">=</span><span class="s">"https://www.okta.com/"</span><span class="p">&gt;</span>Okta<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
          <span class="p">&lt;/</span><span class="nt">h5</span><span class="p">&gt;</span>

          <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
            A tutorial written by<span class="si">{</span><span class="dl">"</span><span class="s2"> </span><span class="dl">"</span><span class="si">}</span>
            <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="p">=</span><span class="s">"https://profile.fishbowlllc.com"</span><span class="p">&gt;</span>Nik Fisher<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
          <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nc">Col</span><span class="p">&gt;</span>
      <span class="p">&lt;/</span><span class="nc">Row</span><span class="p">&gt;</span>

      <span class="p">&lt;</span><span class="nt">br</span><span class="p">&gt;&lt;/</span><span class="nt">br</span><span class="p">&gt;</span>

      <span class="p">&lt;</span><span class="nc">Row</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nc">Col</span> <span class="na">sm</span><span class="p">=</span><span class="si">{</span><span class="mi">12</span><span class="si">}</span> <span class="na">className</span><span class="p">=</span><span class="s">"text-center"</span><span class="p">&gt;</span>
          <span class="p">&lt;</span><span class="nc">Card</span> <span class="na">style</span><span class="p">=</span><span class="si">{</span><span class="p">{</span> <span class="na">width</span><span class="p">:</span> <span class="dl">"</span><span class="s2">21.5em</span><span class="dl">"</span><span class="p">,</span> <span class="na">margin</span><span class="p">:</span> <span class="dl">"</span><span class="s2">0 auto</span><span class="dl">"</span> <span class="p">}</span><span class="si">}</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nc">Card</span><span class="p">.</span><span class="nc">Header</span><span class="p">&gt;</span>Already have an Okta Account?<span class="p">&lt;/</span><span class="nc">Card</span><span class="p">.</span><span class="nc">Header</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nc">Card</span><span class="p">.</span><span class="nc">Body</span><span class="p">&gt;</span>
              <span class="p">&lt;</span><span class="nc">Link</span> <span class="na">to</span><span class="p">=</span><span class="s">"Profile"</span><span class="p">&gt;</span>Login Here<span class="p">&lt;/</span><span class="nc">Link</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nc">Card</span><span class="p">.</span><span class="nc">Body</span><span class="p">&gt;</span>
          <span class="p">&lt;/</span><span class="nc">Card</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nc">Col</span><span class="p">&gt;</span>
      <span class="p">&lt;/</span><span class="nc">Row</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nc">Container</span><span class="p">&gt;</span>
  <span class="p">);</span>
<span class="p">};</span>

<span class="k">export</span> <span class="k">default</span> <span class="nx">Home</span><span class="p">;</span>
</code></pre></div></div>

<p>This page uses the <code class="language-plaintext highlighter-rouge">Redirect</code> component from wouter combined with the <code class="language-plaintext highlighter-rouge">useOktaAuth</code> hook to redirect authenticated users to the profile page. The page also serves as a landing page with some additional information about your application.</p>

<p>Finally, you will need to update your <code class="language-plaintext highlighter-rouge">App.js</code> file with the following code.</p>

<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">React</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="dl">"</span><span class="s2">./App.css</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="p">{</span> <span class="nx">Router</span><span class="p">,</span> <span class="nx">Route</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">wouter</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="p">{</span> <span class="nx">Security</span><span class="p">,</span> <span class="nx">LoginCallback</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@okta/okta-react</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">OktaAuth</span><span class="p">,</span> <span class="nx">toRelativeUrl</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@okta/okta-auth-js</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="nx">Home</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./Pages/Home</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="nx">Profile</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./Pages/Profile</span><span class="dl">"</span><span class="p">;</span>

<span class="k">import</span> <span class="dl">"</span><span class="s2">bootstrap/dist/css/bootstrap.min.css</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">issuer</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">REACT_APP_OKTA_ISSUER</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">clientId</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">REACT_APP_OKTA_CLIENTID</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">redirect</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">REACT_APP_OKTA_APP_BASE_URL</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">/callback</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">class</span> <span class="nx">App</span> <span class="kd">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">Component</span> <span class="p">{</span>
  <span class="kd">constructor</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">super</span><span class="p">(</span><span class="nx">props</span><span class="p">);</span>

    <span class="k">this</span><span class="p">.</span><span class="nx">oktaAuth</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">OktaAuth</span><span class="p">({</span>
      <span class="na">issuer</span><span class="p">:</span> <span class="nx">issuer</span><span class="p">,</span>
      <span class="na">clientId</span><span class="p">:</span> <span class="nx">clientId</span><span class="p">,</span>
      <span class="na">redirectUri</span><span class="p">:</span> <span class="nx">redirect</span><span class="p">,</span>
    <span class="p">});</span>

    <span class="k">this</span><span class="p">.</span><span class="nx">restoreOriginalUri</span> <span class="o">=</span> <span class="k">async</span> <span class="p">(</span><span class="nx">_oktaAuth</span><span class="p">,</span> <span class="nx">originalUri</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span>
        <span class="nx">toRelativeUrl</span><span class="p">(</span><span class="nx">originalUri</span> <span class="o">||</span> <span class="dl">"</span><span class="s2">/</span><span class="dl">"</span><span class="p">,</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">origin</span><span class="p">)</span>
      <span class="p">);</span>
    <span class="p">};</span>
  <span class="p">}</span>

  <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(</span>
      <span class="p">&lt;</span><span class="nc">Router</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nc">Security</span>
          <span class="na">oktaAuth</span><span class="p">=</span><span class="si">{</span><span class="k">this</span><span class="p">.</span><span class="nx">oktaAuth</span><span class="si">}</span>
          <span class="na">restoreOriginalUri</span><span class="p">=</span><span class="si">{</span><span class="k">this</span><span class="p">.</span><span class="nx">restoreOriginalUri</span><span class="si">}</span>
        <span class="p">&gt;</span>
          <span class="p">&lt;</span><span class="nc">Route</span> <span class="na">path</span><span class="p">=</span><span class="s">"/"</span> <span class="na">component</span><span class="p">=</span><span class="si">{</span><span class="nx">Home</span><span class="si">}</span> <span class="p">/&gt;</span>
          <span class="p">&lt;</span><span class="nc">Route</span> <span class="na">path</span><span class="p">=</span><span class="s">"/callback"</span> <span class="na">component</span><span class="p">=</span><span class="si">{</span><span class="nx">LoginCallback</span><span class="si">}</span> <span class="p">/&gt;</span>
          <span class="p">&lt;</span><span class="nc">Route</span> <span class="na">path</span><span class="p">=</span><span class="s">"/Profile"</span> <span class="na">component</span><span class="p">=</span><span class="si">{</span><span class="nx">Profile</span><span class="si">}</span> <span class="p">/&gt;</span>
        <span class="p">&lt;/</span><span class="nc">Security</span><span class="p">&gt;</span>
      <span class="p">&lt;/</span><span class="nc">Router</span><span class="p">&gt;</span>
    <span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="k">export</span> <span class="k">default</span> <span class="nx">App</span><span class="p">;</span>
</code></pre></div></div>

<p>Version 6.0 of the <code class="language-plaintext highlighter-rouge">@okta/okta-react</code> library includes a few changes to be aware of, depending on which version of the package you most recently used.</p>

<p>First, you must provide the <code class="language-plaintext highlighter-rouge">restoreOriginalUri</code> property in the <code class="language-plaintext highlighter-rouge">&lt;Security&gt;</code> component. If you were previously using version 4.x, you will notice that you need to inject the <code class="language-plaintext highlighter-rouge">OktaAuth</code> object into the <code class="language-plaintext highlighter-rouge">Security</code> component rather than the issuer, client ID, and other information. You can read more about these changes on <a href="https://github.com/okta/okta-react#migrating-between-versions">Okta’s React GitHub page</a>.</p>

<p>Here you are also importing the <code class="language-plaintext highlighter-rouge">bootstrap</code> CSS.</p>

<p>Finally, you are setting up the routing by wrapping the wouter <code class="language-plaintext highlighter-rouge">Router</code> in Okta’s <code class="language-plaintext highlighter-rouge">Security</code> component. This will give your routes access to the Okta API.</p>

<h2 id="run-your-react-application">Run your React application</h2>

<p>Your application is now complete. You can run it using <code class="language-plaintext highlighter-rouge">npm start</code> and navigate to <code class="language-plaintext highlighter-rouge">http://localhost:3000</code>. From there you click the <strong>Login</strong> button, which will display the Okta login screen. Once you’ve logged in successfully you are redirected to the <code class="language-plaintext highlighter-rouge">Profile</code> page.</p>

<p><img src="/assets-jekyll/blog/react-routing/react-routing-demo-64d093ec7b1b16d982ae2ee20bfd8c4891367ec70ae18e1b9d618e487e004337.png" alt="React routing demo" width="800" class="center-image" /></p>

<h2 id="learn-more-about-react">Learn more about React</h2>

<p>With Okta React v6.0+, you no longer need access to the <code class="language-plaintext highlighter-rouge">react-router</code> package to set up routing in your React application. This version should make it easier and cleaner to set up Reach Router, Wouter, or to bypass using a router altogether.</p>

<p>You can find the example code from this tutorial in the <a href="https://github.com/oktadev/okta-react-routing-example">oktadev/okta-react-router-example</a> project on GitHub.</p>

<p>If you liked this tutorial, you might like these others:</p>

<ul>
  <li><a href="/blog/2020/08/26/react-hooks">Build a Simple React Application Using Hooks</a></li>
  <li><a href="/blog/2020/11/23/quick-graphql-react-app">Quickly Consume a GraphQL API from React</a></li>
  <li><a href="/blog/2020/01/20/build-reusable-react-components">Build Reusable React Components </a></li>
</ul>

<p>Make sure you follow us on <a href="https://twitter.com/oktadev">Twitter</a> and subscribe to our <a href="https://www.youtube.com/c/oktadev">YouTube</a> channel. If you have any questions, or you want to share what tutorial you’d like to see next, please comment below.</p>

Build a Secure SPA with React Routing