next-generate-path 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# next-generate-path
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/next-generate-path)
|
|
4
|
+
|
|
3
5
|
Type-safe `generatePath()` for Next.js. Autocomplete for every route, params enforced at compile time.
|
|
4
6
|
|
|
5
7
|
## The problem
|
|
6
8
|
|
|
7
|
-
Next.js [typed routes](https://nextjs.org/docs/app/api-reference/config/next-config-js/typedRoutes) give you type safety on `<Link href>`, `redirect()`, etc.
|
|
9
|
+
Next.js [typed routes](https://nextjs.org/docs/app/api-reference/config/next-config-js/typedRoutes) give you type safety on `<Link href>`, `redirect()`, etc. However, dynamic routes like `/blog/[slug]` don't appear in autocomplete. You have to know the pattern and manually write template literals. There's no way to discover what routes exist or what params they need.
|
|
8
10
|
|
|
9
11
|
## The solution
|
|
10
12
|
|
|
@@ -17,13 +19,13 @@ generatePath("/blog/[slug]", { slug: "hello-world" });
|
|
|
17
19
|
// ^ autocomplete shows all routes ^ params are required and type-checked
|
|
18
20
|
|
|
19
21
|
generatePath("/about");
|
|
20
|
-
// => "/about"
|
|
22
|
+
// => "/about" (static routes need no params)
|
|
21
23
|
|
|
22
24
|
generatePath("/blog/[slug]");
|
|
23
25
|
// TS error: expected 2 arguments, got 1
|
|
24
26
|
```
|
|
25
27
|
|
|
26
|
-
The return type is compatible with Next.js's `RouteImpl`, so it works directly with `<Link>`, `redirect()`, and `router.push()`
|
|
28
|
+
The return type is compatible with Next.js's `RouteImpl`, so it works directly with `<Link>`, `redirect()`, and `router.push()` without any casts.
|
|
27
29
|
|
|
28
30
|
```tsx
|
|
29
31
|
// All of these are fully type-safe
|
|
@@ -79,7 +81,7 @@ generatePath("/about");
|
|
|
79
81
|
// => "/about"
|
|
80
82
|
```
|
|
81
83
|
|
|
82
|
-
### Dynamic routes
|
|
84
|
+
### Dynamic routes (`[param]`)
|
|
83
85
|
|
|
84
86
|
```tsx
|
|
85
87
|
generatePath("/blog/[slug]", { slug: "hello-world" });
|
|
@@ -95,9 +97,9 @@ generatePath("/products/[id]/reviews", { id: "42" });
|
|
|
95
97
|
// => "/products/42/reviews"
|
|
96
98
|
```
|
|
97
99
|
|
|
98
|
-
### Catch-all routes
|
|
100
|
+
### Catch-all routes (`[...param]`)
|
|
99
101
|
|
|
100
|
-
Catch-all params accept `string[]
|
|
102
|
+
Catch-all params accept `string[]`. Segments are joined with `/`:
|
|
101
103
|
|
|
102
104
|
```tsx
|
|
103
105
|
generatePath("/docs/[...segments]", { segments: ["guides", "routing"] });
|
|
@@ -107,7 +109,25 @@ generatePath("/docs/[...segments]", { segments: ["getting-started"] });
|
|
|
107
109
|
// => "/docs/getting-started"
|
|
108
110
|
```
|
|
109
111
|
|
|
110
|
-
###
|
|
112
|
+
### API routes (`route.ts`)
|
|
113
|
+
|
|
114
|
+
API route handlers are included in the `ParamMap` too, so `generatePath` works for building API URLs:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
generatePath("/api/health");
|
|
118
|
+
// => "/api/health"
|
|
119
|
+
|
|
120
|
+
generatePath("/api/products/[id]", { id: "42" });
|
|
121
|
+
// => "/api/products/42"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
This is useful for `fetch` calls where you want type-safe API paths:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
const res = await fetch(generatePath("/api/products/[id]", { id: productId }));
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Route groups (`(folder)`)
|
|
111
131
|
|
|
112
132
|
Route groups don't affect URLs. A page at `app/(marketing)/pricing/page.tsx` is just `/pricing`:
|
|
113
133
|
|
|
@@ -125,6 +145,8 @@ Next.js with `typedRoutes: true` generates a `ParamMap` interface in `.next/type
|
|
|
125
145
|
interface ParamMap {
|
|
126
146
|
"/": {}
|
|
127
147
|
"/about": {}
|
|
148
|
+
"/api/health": {}
|
|
149
|
+
"/api/products/[id]": { id: string }
|
|
128
150
|
"/blog/[slug]": { slug: string }
|
|
129
151
|
"/products/[id]": { id: string }
|
|
130
152
|
"/products/[id]/reviews": { id: string }
|
|
@@ -144,9 +166,9 @@ declare module "next-generate-path" {
|
|
|
144
166
|
}
|
|
145
167
|
```
|
|
146
168
|
|
|
147
|
-
Since `.next/types/**/*.ts` is already in your tsconfig's `include`, TypeScript picks it up automatically
|
|
169
|
+
Since `.next/types/**/*.ts` is already in your tsconfig's `include`, TypeScript picks it up automatically. No manual wiring needed.
|
|
148
170
|
|
|
149
|
-
The `generatePath` function uses **conditional tuple types** to require params only when the route has them, and returns a **template literal type** (e.g. `` `/blog/${string}` ``) that Next.js's `RouteImpl` accepts
|
|
171
|
+
The `generatePath` function uses **conditional tuple types** to require params only when the route has them, and returns a **template literal type** (e.g. `` `/blog/${string}` ``) that Next.js's `RouteImpl` accepts. This means the result works directly with `<Link>`, `redirect()`, and `router.push()`.
|
|
150
172
|
|
|
151
173
|
## API
|
|
152
174
|
|
|
@@ -158,9 +180,9 @@ import { generatePath } from "next-generate-path";
|
|
|
158
180
|
|
|
159
181
|
Returns the resolved URL string. Params are required for dynamic routes and omitted for static routes.
|
|
160
182
|
|
|
161
|
-
- **`route`**
|
|
162
|
-
- **`params`**
|
|
163
|
-
- **Returns**
|
|
183
|
+
- **`route`** - A route pattern string (autocompleted from your app's routes)
|
|
184
|
+
- **`params`** - An object of param values (required when the route has dynamic segments)
|
|
185
|
+
- **Returns** - The resolved URL, typed as a template literal compatible with Next.js's `RouteImpl`
|
|
164
186
|
|
|
165
187
|
Param values are URI-encoded. Catch-all params (`string[]`) are joined with `/`.
|
|
166
188
|
|