8

I'm creating a library which includes dependency of react-router-dom. There are some components in which I'm using react-router-dom NavLink, for example, let's name it Header -

Header.tsx

export const Header = () => (
  <div>
    <NavLink to="/home">Home</NavLink>
  </div>
);

Bear in mind that this is just an example, to understand how I'm using the react-router-dom elements. So after building and publishing this library, I want to use it in my main react project, where I include this Header component and I have a parent BrowserRouter wrapper, so it looks something like this -

App.tsx

export const App = () => (
  <BrowserRouter>
    <Header />
  </BrowserRouter>
);

But instead of rendering the page, it gives the following error:

Invariant failed: You should not use <NavLink> outside a <Router>

Any ideas what could be wrong and how to resolve this? React version is 16 in the parent project and v17 in the library. Router versions are 5.3.0 in both projects.

Could it be caused by the different react versions?

Vdas Dorls
  • 485
  • 2
  • 8
  • 19
  • I know there can be problems when trying to access `useLocation` when the `Switch` and the `BrowserRouter` are both in the App component and the way to solve it is to put the `BrowserRouter` in the index.js. Maybe this weird problem would suggest that the same fix could work for you. Try putting `BrowserRouter` in the index.js. – srWebDev Sep 06 '21 at 10:26
  • Hmm, that unfortunately didn't help :( – Vdas Dorls Sep 07 '21 at 10:34
  • Can you try the answers to this question? Not sure what's the problem, but just to try solutions: https://stackoverflow.com/questions/55552147/invariant-failed-you-should-not-use-route-outside-a-router – Iván Sep 08 '21 at 13:55
  • can you post the code along with the import statements? – Sachin Ananthakumar Sep 13 '21 at 05:05
  • You say you're using a different version of React in your library? Importing two versions of React will usually break your code. In your library are `react` and `react-router-dom` `dependencies` or `peerDependencies`? – sallf Sep 13 '21 at 23:08
  • Have you ever solved this issue @VdasDorls? I'm facing the exact same problem, and tried all suggestions from a few places, none helped :( – Mladen Oršolić Jun 17 '23 at 21:53

7 Answers7

3

There is no clear information or evidence on why is your code breaking based on the information you have given.

With React-router-dom, you must put all your NavLink, Switch, Route, Link tags inside your main <BrowserRouter> </BrowserRouter> tag.

But the example you have shown in the question works without any issue

Header.js

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

const Header = () => {

   return(
       <div>
        <NavLink to="home"> Take Me Home </NavLink>
       </div>
)
}
export default Header

here is App.js

    import React from "react"
    import Header from "./Header"
    import {BrowserRouter as Router, NavLink} from "react-router-dom"
   // importing BrowserRouter as a Router is not required, it's just standard practice
    
    cosnt App = () => {
       <div>
          <Router>
            <h1> Hello </h1>
            <NavLink to="about"> About </NavLink>
            <Header />
          </Router>
       </div>
    }
    export default App

This code above works without any hassle, Although your code should work, as it's not working, you should first check again for any misplacement of imports, typo

if still doesn't work you should look into React version conflicts, it's always advised to use the latest version in your parent project.

1

The error indicates that the Header component isn't wrapped by Router component.

You haven't shared the BrowserRouter code, but make sure that BrowserRouter starts with <Router> and ends with </Router>.

bentz123
  • 1,081
  • 7
  • 16
  • 2
    this might be more appropriate as a comment instead – Noam Yizraeli Sep 11 '21 at 18:41
  • 1
    `BrowserRouter` is the router component in react-router. It's usually imported as `Router` with `import { BrowserRouter as Router } from 'react-router-dom'`, but it doesn't have to be. – sallf Sep 13 '21 at 23:05
1

It might have problems in BrowserRouter.

BrowserRouter should start with <Router> and end with </Router>. Then you should correctly import Header component.

rexdev0211
  • 35
  • 4
0

Yes, just use <Router></Route> <Navlink> it is just when u want to redirect or just go to the URL

Sven Eberth
  • 3,057
  • 12
  • 24
  • 29
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 14 '21 at 19:46
0

You can also use Router as well.

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

export const Header: React.FC = () => {
   return(
       <>
        <NavLink to="home"> Take Me Home </NavLink>
       </>
   )
};

import React from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

export const App: React.FC = () => {
  return (
      <Router history={history}>
        <Header />
        <Routes /> // Your all routes
      </Router>
  );
};

history will help you out used anywhere to push the router. In your components and utils.

history.push('/about');

history.push({
  pathname: '/somewhere',
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
});
Asif vora
  • 3,163
  • 3
  • 15
  • 31
0

I would suggest you double check your imports. Maybe your importing the wrong Header component Or your not importing BrowserRouter correctly as mentioned in the example above

DerekReilly1990
  • 49
  • 2
  • 10
0

I also had a same problem, This is how I solved it. In my case, I was using "rollup" to create the react library, To solve this all I have to do was just provide libraries "react-router-dom", as external dependency,

i mean in rollup.config.js file just update the external tag with below value

export default {
    entry: 'src/index.js',
    dest: 'bundle.js',
    format: 'cjs',
    external: [  "react-router-dom"]
};

https://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency (bit of documentation on external dependency in rollup)

Whichever tool you are using to generate your library, check in the config file is there an option to provide external dependency and update it value and it should work

FYI using

"react": "18.2.0",
"react-router-dom": "^6.6.1",
Manoj TM
  • 110
  • 1
  • 4