Can someone please explain why the following path doesn't work with react router 6 (BrowserRouter)
/path/1.1.1
but the following one does:
/path/1.1.1/
my route configuration is as follows. I am using declarative method i.e. useRoutes
hook for defining the Routes.
const App = () => {
const routes = useRoutes([
{
path: '/',
element: <h1>Hello World</h1>
},
{
path: '/app/:version',
element: <AppUI />
}
])
return (
<div>
{routes}
</div>
)
}
const root = createRoot(document.querySelector('#app'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
Whenever I am trying to hit /path/1.1.1
in Chrom, it throws error saying
Cannot get /path/1.1.1
My webpack config:
module.exports = {
entry: './src/index.tsx',
devtool: 'source-map',
output: {
publicPath: '/',
path: path.join(__dirname, '/build'),
filename: 'index.[hash].js',
},
devServer: {
host: 'localhost',
port: 3003,
open: true,
historyApiFallback: true,
},
module: [...],
plugins: [...],
}
Surprisingly, it works on codesandbox:
What am I missing here ?
It's likely the case that "/path/1.1.1"
is treated as the client requesting a file "1.1.1"
from directory "/path"
whereas "/path/1.1.1/"
is treated as the client requesting the index file from directory "/path/1.1.1"
. The sandbox may "cheat" a little bit since you aren't really running a server there.
To avoid "confusion" I'd suggest passing the app version as a search parameter.
Example:
const App = () => {
const routes = useRoutes([
{
path: '/',
element: <h1>Hello World</h1>
},
{
path: '/app',
element: <AppUI />
}
]);
return (
<div>
{routes}
</div>
)
}
Assume URL path + search "/app?version=1.1.1"
:
import { useSearchParams } from 'react-router-dom';
const AppUI = () => {
const [searchParams] = useSearchParams();
const appVersion = searchParams.get("version"); // "1.1.1"
...
};
Or encode the version in a more URL-friendly format, say replace "."
characters with "_"
underscore characters, converting back to using decimals in the routed component.
console.log("1_1_1".replaceAll("_", "."));
Assume URL path + search "/app/1_1_1"
:
import { useParams } from 'react-router-dom';
const AppUI = () => {
const { version } = useParams();
const appVersion = version.replaceAll("_", ".") // "1.1.1"
...
};