Skip to content

Cannot Destructure Property 'basename' of Null in React Router ​

Problem Statement ​

When using React Router's Link component, you may encounter the error:

Uncaught TypeError: Cannot destructure property 'basename' of 'React2.useContext(...)' as it is null

This error typically occurs in React applications using react-router-dom and breaks navigation functionality. The problem manifests when:

  1. Using routing components (Link, Route, etc.)
  2. Rendering a component outside any router context
  3. Seeing your UI partially or completely fail to render

In the provided Navbar component example, the error appears specifically when using <Link> because it requires router context that hasn't been provided.

Root Cause ​

The core issue is that: The component using Link is not wrapped in a BrowserRouter (or similar routing provider).

React Router relies on React Context to share routing information between components. The useContext hook called inside Link expects a router context, but when no router wraps your components, this context becomes null. Consequently, destructuring operations like const { basename } = useContext(RouterContext) fail with the observed error.

Solution ​

You must wrap your entire application or any component using routing features in a router provider.

Step-by-Step Fix ​

  1. Identify your application's entry point (often src/index.jsx or src/main.jsx)

  2. Import BrowserRouter from react-router-dom

  3. Wrap your root component with <BrowserRouter>

Here's the corrected entry file implementation:

js
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom'; // Import the router provider
import App from './App';

const root = createRoot(document.getElementById('root'));
root.render(
  <StrictMode>
    <BrowserRouter> {/* Wrap the root component */}
      <App />
    </BrowserRouter>
  </StrictMode>
);

Complete Application Structure ​

Ensure components using Link are within BrowserRouter:

js
import { Routes, Route } from 'react-router-dom';
import Navbar from './components/Navbar';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';

function App() {
  return (
    <div className="App">
      <Navbar />
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/about" element={<AboutPage />} />
        <Route path="/*" element={<NotFound />} />
      </Routes>
    </div>
  );
}

export default App;

Key Principles for Router Implementation ​

  1. Single top-level router: Wrap your entire app once in BrowserRouter
  2. Place routing components anywhere inside the router: Link, Routes, Route must be descendants of BrowserRouter
  3. Non-routing components outside <Routes>: Position common elements like Navbar outside the Routes component (but still inside BrowserRouter)
js
// ❌ Incorrect Placement
<Routes>
  <Navbar /> {/* Breaks - should not be direct child of Routes */}
  <Route path="/" element={<HomePage/>} />
</Routes>

// ✅ Correct Placement
<BrowserRouter>
  <Navbar /> {/* Valid - sibling to Routes */}
  <Routes>
    <Route path="/" element={<HomePage/>} />
  </Routes>
</BrowserRouter>

Why This Works ​

  1. Context Provision: BrowserRouter creates the routing context that useContext hooks access
  2. Global Availability: By wrapping the root component, the router context becomes available to all descendants
  3. Prop Avoidance: Eliminates prop-drilling for routing data between components

Additional Considerations ​

Multiple Router Instances ​

js
Only create one `BrowserRouter` near your app root. Multiple routers isolate context and will break navigation between sections of your app.

Dynamic Router Access ​

If you need programmatic router access (e.g., in utility functions), use:

js
import { createBrowserRouter } from 'react-router-dom';

const router = createBrowserRouter([
  { path: '/', element: <App /> }
]);

// Access router instance anywhere with:
router.navigate('/path');

Server-Side Rendering (SSR) ​

For Next.js or Remix, use framework-specific routers instead of BrowserRouter:

js
// Next.js
import Link from 'next/link';

// Remix
import { Link } from '@remix-run/react';

Legacy Versions ​

For React Router v5 and below, use react-router-config if implementing complex route structures.

Conclusion ​

The "Cannot destructure property 'basename' of null" error occurs in React Router when components lack access to router context. The solution is:

  1. Wrap your application root with BrowserRouter
  2. Ensure routing components are descendants of your router
  3. Maintain proper component hierarchy (<Routes> only contains <Route> elements)

This approach initializes the routing context properly, allowing destructuring operations in Link and other routing components to function error-free.