Bind a param every link shares
Some segments sit at the front of nearly every path in an app, such as a locale or a tenant. Passing that value to every link is tedious, so gather it in one place with bindParams.
On this page
Hand over a function that returns the value
bindParams takes a function that returns the params to bind. The href and navigateTo it gives back call that function every time they are called, and fill in the params it supplies.
src/links.tsimport { bindParams } from '@k8ordo/router';
import { locales } from './i18n';
export const { href, navigateTo } = bindParams(() => ({
locale: locales.getLocale(),
}));This site’s own src/links.ts is written exactly this way. locales.getLocale() comes from @k8ordo/i18n and returns the current locale.
The app’s code then imports href and navigateTo from this module rather than from @k8ordo/router.
Use the bound links
Patterns keep their full /:locale/… spelling. The bound locale may be left out, so only the other params are passed. The results in the comments are for a current locale of ja.
import { href, navigateTo } from './links';
href('/:locale/products/:id', { id: '42' }); // '/ja/products/42'
href('/:locale', { locale: 'en' }); // '/en'
navigateTo('/:locale/products');A bound param can still be passed to override it, for a link to another locale’s page, as a language switcher needs.
Since the patterns are spelled as before, the Register check still applies: a pattern the table lacks, or a missing param that is not bound, is a type error as usual.
The function is read on every call
The binding function does not run once, when bindParams is called. It runs every time href or navigateTo does.
A value that differs per request or per URL is therefore read where the link is built, and calling bindParams once at the top level of a module is enough.
Which package supplies the value is the app’s business. The router knows a param’s name and nothing more; it has no idea what a locale is.
Options go third
Even for a pattern whose params are all bound, navigateTo’s options are the third argument. Pass undefined second, in place of the params.
navigateTo('/:locale', undefined, { history: 'replace' });
navigateTo('/:locale', { locale: 'en' }, { history: 'replace' });
navigateTo('/:locale', { history: 'replace' });
Options in second place: a type errorParams and options are both plain objects, so whether the pattern names a param is what decides which the second argument is. When it does, the second argument is always the params.
Pitfall
Passed second around the type check, the options are read as params: history is ignored, and a new history entry is pushed.