Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't add prefixes to paths properly in React router

I'm creating multi language app. I'm using : React Intl; React Router (latest v4); Redux.
Paths in my app are going to be depending on locale:

/ <-- default expecting this to be uk
/en
/ru
/news <-- uk
/en/news
/ru/news

If user has locale = en-US and enters localhost:8080 app redirects him to localhost:8080/en

If user has locale = uk and enters localhost:8080 app shows him component that corresponds to address localhost:8080/ without changing location path-name.

Routers.jsx

const Routes = ({ lang }) => (
  <BrowserRouter basename={lang}>
      <Route render={props => <Header {...props} />} />
      <Switch>
        <Route exact path={`/:${lang}`} component={Landing} />
        <Route exact path={`/:${lang}/news`} component={News} />
        <Route component={FourOhFour} />
      </Switch>
  </BrowserRouter>
);

const mapStateToProps = state => ({ lang: getLang(state.locale) });    
export default connect(mapStateToProps)(Routes);

Currently It's not working as expected.
I got no match in routes config if I enter localhost:8080/ or localhost:8080/en.

like image 977
Taras Yaremkiv Avatar asked Sep 08 '17 09:09

Taras Yaremkiv


1 Answers

Here's my way of solving it. Redirecting is working, and prefixes are added to props.

Routers.jsx

const Routes = ({ lang }) => (
  <BrowserRouter>
    <Route render={props => <Header lang={lang} {...props} />} />
    <Switch>
      <RootRouter
        exact
        path={'/:lang(en|ru)?'}
        lang={lang}
        component={Landing}
      />
      <Route
        exact
        path={'/:lang(en|ru)?/news'}
        render={props => <News {...props} lang={lang} />}
      />
      <Route component={FourOhFour} />
    </Switch>
  </BrowserRouter>
);

const mapStateToProps = state => ({ lang: getPrefix(state.locale) });
export default connect(mapStateToProps)(Routes);

RootRouter.jsx

const RootRouter = ({ component: Component, exact, path, lang }) => (
  <Route
    exact={exact}
    path={path}
    render={(props: ContextRouter) =>
      props.location.pathname === '/' && lang !== '' ? (
        <Redirect to={`/${lang}`} />
      ) : (
        <Component {...props} lang={lang} />
      )}
  />
);

Method from header component (Contacts.jsx) that changes locale on Click event:

const changeLang = newLang => () => {
  if (lang !== newLang) {
    const newUrl = switchLangHepler(lang, newLang, location.pathname);
    setLocaleData(newLang);
    localStorage.setItem('lang', String(newLang));
    history.replace(newUrl);
  }
};
like image 122
Taras Yaremkiv Avatar answered Sep 19 '22 11:09

Taras Yaremkiv