Search code examples
reactjsreact-router-domconnected-react-router

Duplicate Parameter in URL React Js / Router


I am trying to build a Multi language React website, I have been struggling until i finally I prepare the structure, and now I am facing a problem which I think due to my misunderstanding of React Routes.

I have a MainLayout Layout which provide Header / Main and Footer which contain links. Using Image would be easy to describe.

  1. Home Page Navigation

HomePage

  1. Category Page Navigation

CategoryPage

  1. When i click again on Power on Category Page

CategoryPage

http://localhost:3000/en/category/power/category/power

App.js

const base = '/:lang([de|en|fr]{2})';
const fallback = '/en';
export const App = ({ store, history }) => {
return(
    <Suspense fallback={<p>...Loading</p>}>
        <I18nextProvider i18n={i18n}>
            <Provider store={store}>
                <ApolloProvider client={client}>
                    <ConnectedRouter history={history}>
                        <Switch>
                            <Route path={base} component={BaseRoutes} />
                            <Redirect to={fallback} />
                        </Switch>
                    </ConnectedRouter>
                </ApolloProvider>
            </Provider>
        </I18nextProvider>
    </Suspense>
)}

Routes.js

const BaseRoutes = ({match}) => {
return (
    <Switch>
        <Route exact path={`${match.url}/`} component={Home} />
        <Route exact path={`${match.url}/:page`} component={Dynamic}/>
        <Route exact path={`${match.url}/category/:category`} component={Category}/>
        <Route exact path={`${match.url}/detail/:url`} component={DetailArticle}/>
    </Switch>
   );
  };
export default withRouter(BaseRoutes);

Main Layout

const MainLayout = (props) => {
return (
    <>
        <Header/>
        <main>
            {props.children}
        </main>
        <Footer/>
    </>
 );
};

Navigation Link In header

<Nav>
      <Nav.Link to={`${match.url}`} as={Link} >{t('home')}</Nav.Link>
      {data.allCategories.map(item => (
       <Nav.Link to={`${match.url}/category/${item.url}`} as={Link}>
            {item.name}
       </Nav.Link>
        ))}
</Nav>

Should I test in every component the match URL ? Or there is any other way to do that ? I am using the latest Version of React / React Router

Thanks for any Tips or Help!

Livd Demo: https://codesandbox.io/s/react-nav-bug-5o2fyx


Solution

  • The problem lies in how you make the "to" param of the Nav.Link:

    <Nav.Link to={`${match.url}/category/${item.url}`} as={Link}>
      {item.name}
    </Nav.Link>
    

    The match.url is your current url, then you are concatenating it with the /category/${item.url}, so it's likely to have a repetition because you always use the previous url.

    A possible solution could be use the lang parameter that you have assigned:

    <Nav.Link
      to={`/${match.params.lang}/category/${item.url}`}
      as={Link}
    >
      {item.name}
    </Nav.Link>