tatethurston / nextjs-routes

Type safe routing for Next.js
MIT License
571 stars 23 forks source link

[Question] Non-Link usage #36

Closed Noitidart closed 2 years ago

Noitidart commented 2 years ago

I wanted to use this in a non-link. For example a fetch like fetch('/foo'), is there anyway to typecheck that foo?

I was thinking of doing a type like:

const ResourcePath = Parameters<typeof useRouter>[0]['path'];
const path: ResourcePath = '/foo';
fetch(path);

But it's kind of extra to create a variable to hold path then type that.

tatethurston commented 2 years ago

Hey @Noitidart,

You can make this a bit more ergonomic by importing Route directly.

So you would have:

import type { Route } from "nextjs-routes";

const path: Route["pathname"] = '/foo';
fetch(path);

If you want to remove the variable, you could create a wrapper for fetch:

function fetchPage(url: Route["pathname"]): ReturnType<typeof fetch> {
  return fetch(url);
}

Alternatively, you could patch the types for fetch, but that would prevent fetching any path that wasn't a Nextjs route, and would only work for static routes.

This will work for static routes, but fetch won't interpolate query parameters for Next-style dynamic pathnames (eg /foos/[foo]). I'm not aware of any utilities that Nextjs exports for achieving that, so you would want to put something together if you have dynamic pathnames in your application.

Is there a particular reason you need to avoid using push from useRouter?

Noitidart commented 2 years ago

Thanks very much for your detailed reply. I wanted to use this for my api routes as well. For pages I would use useRouter.push thanks so much for this awesome lib!

tatethurston commented 2 years ago

Ah got it, I’ll think on the API use case some more. There’s certainly an opportunity for a better typescript story there. Thanks @Noitidart !

Noitidart commented 2 years ago

Thanks very much sir!

tatethurston commented 2 years ago

@Noitidart what do you think about the following API?

+ import { route } from 'nextjs-routes';

- const ResourcePath = Parameters<typeof useRouter>[0]['path'];
- const path: ResourcePath = '/foo';
- fetch(path);
+ fetch(route({ pathname: '/foo' }));

route would be a runtime export from nextjs-routes that performs the same dynamic query interpolation as Next's link, so route({ pathname: '/foos/[foo]', query: { foo: 'bar' }}) would yield /foos/bar. route would be typed identical to Link.

Noitidart commented 2 years ago

Woow! That's amazing! Thanks very much for asking!

tatethurston commented 2 years ago

This is released in v0.0.21

Noitidart commented 2 years ago

Thank you man!!