Skip to content

Instantly share code, notes, and snippets.

@mctep
Last active April 4, 2018 13:14
Show Gist options
  • Save mctep/d1d72bfee1ae807e84ebd0a2bb9ee4c4 to your computer and use it in GitHub Desktop.
Save mctep/d1d72bfee1ae807e84ebd0a2bb9ee4c4 to your computer and use it in GitHub Desktop.
React Router 4 prefix support (Draw)
type PrefixParser = (prefix?: string) => string;
interface RoutePrefixSettings {
parse: PrefixParser;
defaultPrefix: string;
}
interface RoutePrefixConsumerProps {
routePath: (path: string) => string;
linkPath: (path: string) => string;
prefix: string;
}
function createRoutePrefix(settings: RoutePrefixSettings) {
const { parse, defaultPrefix } = settings;
let currentPrefix = defaultPrefix;
const Provider = (props: { children: React.ReactNode }) => {
const render = ({ match }: RouteComponentProps<{ prefix?: string }>) => {
currentPrefix = parse(match.params.prefix) || defaultPrefix;
return props.children;
};
return <Route path="/:prefix?" render={render} />;
};
const Consumer = (props: {
children: (childProps: RoutePrefixConsumerProps) => JSX.Element;
}) =>
props.children({
routePath: path => `/(${currentPrefix})?${path}`,
linkPath: path =>
currentPrefix === defaultPrefix
? `${path}`
: `/${currentPrefix}${path}`,
prefix: currentPrefix,
});
return { Provider, Consumer };
}
const defaultLocale = 'en';
const supportedLocales = ['en', 'ru'];
const RoutePrefix = createRoutePrefix({
parse: prefix =>
prefix && supportedLocales.includes(prefix) ? prefix : defaultLocale,
defaultPrefix: defaultLocale,
});
const Application = () => (
<RoutePrefix.Provider>
<RoutePrefix.Consumer>
{({ routePath, linkPath, prefix }) => (
<React.Fragment>
<Switch>
<Route
path={routePath('/about')}
render={() => `${prefix} about`}
/>
<Route
exact
path={routePath('/')}
render={() => `${prefix} index`}
/>
<Route render={() => `${prefix} not found`} />
</Switch>
<Link to={linkPath('/')}>Index</Link>
<Link to={linkPath('/about')}>About</Link>
</React.Fragment>
)}
</RoutePrefix.Consumer>
</RoutePrefix.Provider>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment