Skip to content

Instantly share code, notes, and snippets.

@mrcoles
Last active March 5, 2020 17:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrcoles/59d0cff06055779dce8931755dab0efa to your computer and use it in GitHub Desktop.
Save mrcoles/59d0cff06055779dce8931755dab0efa to your computer and use it in GitHub Desktop.
Define your React Router URLs as objects that can be used both in your router and also to generate URL strings.
import { generatePath } from 'react-router';
// ## Route URL
export default class RouteUrl<P extends { [K in keyof P]?: string }> {
constructor(public routePath: string) {}
asPath(params: { [K in keyof P]: string | number | boolean }) {
return generatePath(this.routePath, params);
}
asAbsoluteUrl(params: { [K in keyof P]: string | number | boolean }) {
return _asAbsoluteUrl(this.asPath(params));
}
}
// ## Helpers
const _asAbsoluteUrl = (path = '') =>
`${window.location.protocol}//${window.location.host}${path}`;
import React from 'react';
import { Link, BrowserRouter as Router, Route, RouteComponentProps } from 'react-router-dom';
import RouteUrl from './routeurl';
type IdUrlParams = { id: string };
const HomeUrl = new RouteUrl<{}>('/');
const FooUrl = new RouteUrl<IdUrlParams>('/foo/:id');
const App: React.FunctionComponent<{}> = props => {
return (
<Router>
<Route exact path={HomeUrl.routePath} render={Home} />
<Route path={FooUrl.routePath} render={Foo} />
</Router>
);
};
const Home: React.FunctionComponent<RouteComponentProps<{}>> = props => {
return (
<div>
<h1>Go to foos:</h1>
<ul>
{[1, 2, 3, 4].map(id => (
<li key={id}>
<Link to={FooUrl.asPath({ id })}>{id}</Link>
</li>
))}
</ul>
</div>
);
};
const Foo: React.FunctionComponent<RouteComponentProps<
IdUrlParams
>> = props => {
return (
<div>
<p>
<Link to={HomeUrl.asPath({})}>← Back to home</Link>
</p>
<p>Id is: {props.match.params.id}</p>
</div>
);
};
@mrcoles
Copy link
Author

mrcoles commented Mar 5, 2020

I was looking for a way to reference and generate URLs for my routes in a reusable way. See sample.tsx for usage. Are there more useful packages out there for this? Or any suggested changes in how it works?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment