I need to use a hash router with a basename. I did this with the createHashRouter (React Router 6.8), with the basename property to render the app in the sub-route. When I open /sub/route
in the browser I get the empty page though, only css background is visible.
All of the files and assets are shipped to the app, but the JS is not executed and the root div stays empty.
The code of the Router:
const router = createHashRouter([
{
id: 'root',
path: '/',
element: <App />,
errorElement: <ErrorPage />,
loader: filtersLoader(queryClient),
children: [
{ path: '/', element: <Navigate to="/dashboard/performance" /> },
{
path: '/dashboard',
id: 'dashboard',
errorElement: <ErrorPage />,
loader: dataLoader(queryClient),
element: (
<>
<Header />
<Outlet />
</>
),
children: [
{ index: true, element: <Index /> }
]
},
{
path: 'info',
element: <Info />
}
]
}
], {
basename: '/sub/route'
});
the issue was caused by mixing HashRouter with basename. Getting rid of the basename in createHashRouter solved the issue.
The HashRouter
will basically already just work from whatever directory you deploy/serve the React app from, specifying a basename
doesn't make as much since here as it does for the BrowserRouter
where the routes/links need it as part of their resolved paths.
The
<Router basename>
prop may be used to make all routes and links in your app relative to a "base" portion of the URL pathname that they all share. This is useful when rendering only a portion of a larger app with React Router or when your app has multiple entry points. Basenames are not case-sensitive.
The HashRouter
uses the URL hash for routing, so for example if you add that one has a basename="/sub/route"
then you are specifying that all routes and links operate relative to it where it's rendered. If the app is hosted/served from "https://www.example.com/subA/subB"
then you are effectively saying "https://www.example.com/subA/subB/#/sub/route"
is where the app is running and the browser will need to be navigated to this URL to start the proper routing.
If "/sub/route"
is already where the app is hosted/served from then there's nothing to set as a basename
if you want to keep the default behavior of routing/linking relative to a "/"
path on "https://www.example.com/sub/route/#/"
.
Remove the basename
property from the routing configuration.
const router = createHashRouter([
{
id: 'root',
path: '/',
element: <App />,
errorElement: <ErrorPage />,
loader: filtersLoader(queryClient),
children: [
{ path: '/', element: <Navigate to="/dashboard/performance" /> },
{
path: '/dashboard',
id: 'dashboard',
errorElement: <ErrorPage />,
loader: dataLoader(queryClient),
element: (
<>
<Header />
<Outlet />
</>
),
children: [
{ index: true, element: <Index /> }
]
},
{
path: 'info',
element: <Info />
}
]
}
]);