Search code examples
reactjsreact-router-dom

Long path fails to load with react-router-dom


I have a VerifyEmail route that takes on a JWT token as a parameter. However, it does not load. Is there anyway to get it to load? The route loads if the token is short, about 10 characters long. Anything longer it does not work. I was wondering if there's a limit to the length of the url path for react-router-dom to be causing this problem.

In my App.jsx

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./components/Home"
import Login from "./components/Login"
import Logout from "./components/Logout"
import SignUp from "./components/SignUp"
import Navbar from "./components/Navbar"
import VerifyEmail from "./features/users/VerifyEmail"
import { selectCurrentToken } from './features/auth/authSlice'
import { useSelector } from "react-redux/es/hooks/useSelector";

function App() {
  const auth = useSelector(selectCurrentToken)

  return (
    <>
      <BrowserRouter>
        <Navbar auth={auth} />
        <Routes>
          <Route index element={<Home />} />
          {!auth && <Route path="/login" element={<Login />} />}
          {auth && <Route path="/logout" element={<Logout />} />}
          <Route path="/signup" element={<SignUp />} />
          <Route path="/verify/:token" element={<VerifyEmail />} />
        </Routes>
      </BrowserRouter>
    </>
  )
}

export default App

In my VerifyEmail.jsx

import React from 'react'
import { useParams } from 'react-router-dom'

const VerifyEmail = () => {
  const { token } = useParams()

  return (
    <div>{token}</div>
  )
}

export default VerifyEmail

When I try this link, I get a bad request.

http://localhost:5173/verify/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImUiLCJpYXQiOjE2OTE1NDkwMjcsImV4cCI6MTY5MTU3MDYyN30.HqPtksRbGTxxP8EeFs7XLHfHQLBXleaVil6MYmiKB3Y

(https://i.sstatic.net/zhuzb.png)


Solution

  • The web server is misinterpret your jwt with a file. How is it know the difference between locahost:5173/favicon.ico and localhost:5173/U3MDYyN30.HqPtksRbGTxxP8EeFs7. So it will throw an error Not Found as you show in the image. You have two options to handle this:

    1. If you are using webpack, you can config to disable the dot rule (docs).
     historyApiFallback: {
        disableDotRule: true
     }
    
    1. You can modify the route and pass the JWT as a query parameter
    <Route path="/verify" element={<VerifyEmail />} />
    

    And in your VerifyEmail component, use useQuery to get the value of token

    // http://localhost:5173/verify?token=abcxyx
    import { useQuery } from 'react-router-dom';
    
    function VerifyEmail() {
       let query = useQuery();
       let token = query.get('token');
    
       // Rest of your component logic
    }