2.0.2 • Published 2 years ago

cl-fill-link v2.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

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.


2.0.2

2 years ago

2.0.1

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

2.0.0

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago