React Authentication By Example: React Router 6

Hey all,

I’m currently working through the React Authentication By Example: Using React Router 6 guide for my self-hosted site, which is running React v18.2.0, React Router v6.3.0, & React Scripts v5.0.1.

I’m at the “Add Route Guards to React” section & created src/pages/profile-page.js per docs to test things out with the <AuthenticationGuard/> element, prior to rolling out for my production pages. My example.com/profile page redirects to my Auth0 login as expected, for auth.example.com, however after signing in this returns a blank screen & the following error in my browser console:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <ProfilePage />. Did you accidentally export a JSX literal instead of a component?

Anyone have any idea what’s going on here?

I have a pastebin for my index.js, App.js, auth0-provider-with-navigate.js, authentication-guard.js, profile-page.js & callback-page.js, yet will share what I have for App.js below.

App.js:

import './App.css';
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { Auth0ProviderWithNavigate } from "./auth0-provider-with-navigate";
import { AuthenticationGuard } from "./components/authentication-guard";
import { ProfilePage } from "./pages/profile-page";
import { CallbackPage } from "./pages/callback-page";

function App() {
  return (
  <BrowserRouter>
    <Auth0ProviderWithNavigate>
      <Routes>
        <Route path='/profile' element={<AuthenticationGuard component={<ProfilePage/>} />} />
        <Route path="/callback" element={<CallbackPage />} />
      </Routes>
    </Auth0ProviderWithNavigate>
  </BrowserRouter>
  );
}
export default App;

Thanks,
Nick

1 Like

I had the same error and after further investigation, I went back to the sample repository and found out that instead of:

<AuthenticationGuard component={<ProfilePage />} />

like in the guide, the sample repository actually uses the one below which works for me.

<AuthenticationGuard component={ProfilePage} />

https://github.com/auth0-developer-hub/spa_react_javascript_hello-world_react-router-6/blob/main/src/app.js

1 Like

Thanks.

That worked for my test Profile page, yet doesn’t for components with props (I’d never before seen a component nested within an element under Routes).

I guess now the question is how to transform the below:
<Route path='/data' element={<DataPage data1={{var1, var2, var3}} data2={var4} data3={var5}/>} />

To something with props under React Router 6:
<Route path='/data' element={<AuthenticationGuard component={DataPage}...

How would I pass <AuthenticationGuard/> in Routes against components with props? Only errors are coming up from my end.

@dan-auth0 , @bmotoche are you able to help on that front? Thank you!

2 Likes

Thanks @konrad.sopala.

For reference: I’m currently passing my components through Routes the following way:

<Route path='/:siteID/history/*' element={<History data={{siteID, stateID, cityID}} customerID={''}/>} />
<Route path='/:siteID/history/:page' element={<History data={{siteID, stateID, cityID}} customerID={''}/>} />

I’d never before seen examples of nesting Route elements with components while properly passing props in React 18 / Router 6, especially with <AuthenticationGuard>.

My question here is how are props passed when changing “element={<History” to “element={History}”?

Thanks, @konrad.sopala, for connecting the dots.
Hi @ymonye, what @bren.codes and @nikyo suggested is correct. We should pass the ProfilePage as follows:

<AuthenticationGuard component={ProfilePage} />

We fixed this in the guide. Thanks for pointing it out.

1 Like

Thanks, but how are props passed after changing component={<DataPage to component={DataPage

The above breaks the code

@bmotoche also mentioning a part that needs to be changed in the article in order to make it work.

Instead of:

<Route
    path="/profile"
    element={<AuthenticationGuard component={<ProfilePage />} />}
  />

it should be:

 <Route
    path="/profile"
    element={<AuthenticationGuard component={ProfilePage} />}
  />
1 Like

Hey team,

How do I implement <AuthenticationGuard> into elements with props? Following your guide, it’s not very clear.

Prior to AuthenticationGuard, my routes (under React Router 6) are setup as:

<Route path='/:siteID/history/*' element={<History data={{siteID, stateID, cityID}} customerID={''}/>} />

This History.js component is setup as:

import {useEffect, useState} from 'react';
import {useLocation, useParams} from 'react-router-dom'
import '../App.css';

function History ({data, customerID}){
    //Main code...
    return(
       //Return code...
    )
}

export default History;

After following through the guide, this Route was revised to:

<Route path='/:siteID/history/*' element={<AuthenticationGuard component={History} data={{siteID, stateID, cityID}} customerID={''}/>} />

The main problem is props are not being passed to the <History> component. I’d tried various combinations with the braces, as well as Google search for examples of passing props to components nested with elements, with zero luck.

The below fails as well:

<Route path='/:siteID/history/*' element={<AuthenticationGuard component={History data={{siteID, stateID, cityID}} customerID={''}}/>} />

How are props supposed to be passed within <AuthenticationGuard> gated Routes?

Thanks

1 Like

Hello @ymonye, we found a solution that can help you with the use case of passing props to a component that you need to protect with the <AuthenticationGuard>.

  1. You can update the src/components/authentication-guard.js to the following content:
import { withAuthenticationRequired } from "@auth0/auth0-react";
import React from "react";
import { PageLoader } from "./page-loader";

export const AuthenticationGuard = ({ component, ...props }) => {
  const Component = withAuthenticationRequired(component, {
    onRedirecting: () => (
      <div className="page-layout">
        <PageLoader />
      </div>
    ),
  });

  return <Component {...props} />;
};
  1. Since the AuthenticationGuard expects a ComponentType, like ProtectedPage, rather than a React Element, like <ProtectedPage />, you should pass the props for your component to the AuthenticationGuard component as follows in the src/app.js file:
<Route path="/:siteID/history/*" element={<AuthenticationGuard component={History} data={{siteID, stateID, cityID}} customerID={''} />} />

While passing props to a guarded component is not common as they are usually top-level components, we can include an aside in the Developer Guide if you find this solution suitable. Please let us know if this works well for you.

Thank you for helping us make this guide stronger.

2 Likes




I don’t know why I am getting this error

1 Like

hi can anyone help please

1 Like

Tagging you @byron.motoche for visibility

1 Like

Hi @dev_bas, Welcome to the Auth0 Community.

The error you’re getting is related to how you’re passing the Login component as the element prop to the <Route> component. With React Router v6, you should use regular elements instead of components (or element types) for rendering. You can read more information about its benefits in the migration guide from React Router v5 to React Router v6.

To fix the issue, do the following in your App component:

function App() {
  return (
    <main>
      <Routes>
        <Route path="/" element={<Login />} />
        <Route
          path="/profile"
          element={<AuthenticationGuard component={Dashboard} />}
        />
      </Routes>
    </main>
  );
}

Please let us know if this works well for you.

1 Like

6 posts were split to a new topic: Full Stack Architecture + Auth0

Something to add regarding passing props here…

You’ll also need to go to each individual component file where you are receiving the props and add them there on two places:

export const Dashboard = ({ addPropsHere }) => {

  return (
    <PageLayout addPropsHere={addPropsHere}>

This is if you want to pass props to the NavBar for some reason, and then you need to have the data in both the NavBar and the /route component.

1 Like

Is there any way in react router 6 to have the role based routing in react apps, mainly with “AuthenticationRequired” function.

1 Like

Hello! Welcome to the Auth0 Community. Yes, there is! I am working on a sample that may show how to do that. I may not be able to share the full-sample too soon but I can definitely share the code snippets within the next weeks.

Stay tuned, please!

1 Like

Thanks for sharing this insight with us :pray: :muscle:

1 Like