cl-fill-link
v2.0.2
Published
Fill generated nextjs links with dynamic values
Downloads
206
Maintainers
Readme
Fill dynamic nextjs links
Note
This program is intended to be used with generate-next-links but it can be used with any input that follows nextjs dynamic routes.
It also offers a type-safe implementation.
Install
yarn add cl-fill-link
Usage
import { fillLink } from 'cl-fill-link';
enum AppLink {
CUSTOMERID_SETTINGS_VIEW = '/[customerId]/settings/[view]',
BLOG_OPTIONAL_CATCHALL_SLUG = '/blog/[[...slug]]',
}
// returns: '/some-id/settings/templates'
fillLink(AppLink.CUSTOMERID_SETTINGS_VIEW, {
customerId: 'some-id',
view: 'templates',
});
// returns: '/blog/category/music/jazz/miles-davis'
fillLink(AppLink.BLOG_OPTIONAL_CATCHALL_SLUG, {
slug: ['category', 'music', 'jazz', 'miles-davis'],
});
Type safety
If a key is missing, has an inappropriate type or does not exist, TypeScript will complain
// TypeScript Error:
// Property 'customerId' is missing in type '{ view: string; }'
// but required in type '{ customerId: PrimitiveTypeConstraint; }'
fillLink('/[customerId]/settings/[view]', {
view: 'templates',
});
// TypeScript Error:
// Object literal may only specify known properties,
// but 'view2' does not exist in type
fillLink('/[customerId]/settings/[view]', {
view2: 'templates',
customerId: 1,
});
// TypeScript Error:
// Type 'string[]' is not assignable to
// type 'PrimitiveTypeConstraint'.
fillLink('/[customerId]/settings/[view]', {
view: ['templates'],
customerId: 1,
});
The expected type for catch-all routes is always an array of strings. For optional-catch-all routes, [[...slug]]
an empty array is accepted, as optional catch all routes includes the index of the path, while catch all routes, [...slug]
only accepts a non-empty array.
// OK
fillLink('/hello/[...there]', { there: ['something'] });
// TypeScript Error:
// Type 'string' is not assignable to type
// '[PrimitiveTypeConstraint, ...PrimitiveTypeConstraint[]]'
fillLink('/hello/[...there]', { there: 'something' });
// TypeScript Error:
// Source has 0 element(s) but target requires 1
fillLink('/hello/[...there]', { there: [] });
// OK
fillLink('/hello/[[...there]]', { there: [] });
// OK
fillLink('/hello/[[...there]]', { there: ['something'] });
// TypeScript Error:
// Type 'string' is not assignable to type 'PrimitiveTypeConstraint[]'
fillLink('/hello/[[...there]]', { there: 'something' });
Query Params
Use the $query
property to specify an object containing query-parameters. The $
sign is prefixed to avoid collision with an actual query
key in the link itself.
Note that properties of the $query
object must have values of a primitive
type.
enum AppLink {
CATEGORYID_CONTENT_GENRE = '/[categoryId]/content/[genre]',
}
// returns: '/music/content/jazz?artist=miles-davis&tune=so-what&year=1959&autoplay=true'
fillLink(AppLink.CATEGORYID_CONTENT_GENRE, {
categoryId: 'music',
genre: 'jazz',
$query: {
artist: 'miles-davis',
tune: 'so-what',
year: 1959,
autoplay: true,
},
});
The parameters are each encoded into valid URI
components and thus you can safely do stuff like this
enum AppLink {
CATEGORYID_CONTENT_GENRE = '/[categoryId]/content/[genre]',
}
// returns: '/music/content/jazz?artist=miles%20davis&tune=so%20what%20%7C%20kind%20of%20blue&year=%5B1959%5D'
fillLink(AppLink.CATEGORYID_CONTENT_GENRE, {
categoryId: 'music',
genre: 'jazz',
$query: {
artist: 'miles davis',
tune: 'so what | kind of blue',
year: '[1959]',
},
});
Why
Nextjs natively supports the behavior this program accomplishes, as seen here. However, that is only useful within that Link
component. Sometimes it's useful for a filled dynamic link to be constructed outside the Link
component. This small and simple program is for exactly such a case. And then it's type-safe.