https://github.com/zoontek/next-type-routes
An experiment to make next.js routes usage safer.
https://github.com/zoontek/next-type-routes
Last synced: 2 days ago
JSON representation
An experiment to make next.js routes usage safer.
- Host: GitHub
- URL: https://github.com/zoontek/next-type-routes
- Owner: zoontek
- License: mit
- Created: 2022-08-15T12:57:51.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2022-09-21T08:54:18.000Z (almost 4 years ago)
- Last Synced: 2026-04-23T00:09:38.978Z (2 months ago)
- Language: TypeScript
- Homepage:
- Size: 703 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# 🔬 next-type-routes
[](https://github.com/zoontek/next-type-routes/blob/main/LICENSE)
[](https://www.npmjs.org/package/next-type-routes)
[](https://bundlephobia.com/result?p=next-type-routes)
An experiment to make next.js routes usage safer.
**Heavily inspired by my work on [@swan-io/chicane](https://github.com/swan-io/chicane)**
_⚠️ Don't use this in production (yet)!_
## Installation
```bash
$ yarn add next-type-routes
# --- or ---
$ npm install --save next-type-routes
```
## Quickstart
First, you have to generate the typed routes functions. For that, I recommend using npm scripts:
```json
"scripts": {
"type-routes": "type-routes src/routes.ts",
"dev": "yarn type-routes && next dev",
"build": "yarn type-routes && next build",
```
When ran, this command parse your pages tree and generates a TS file (`src/routes.ts`) which looks like this:
```ts
import { createTypedFns } from "next-type-routes";
export const {
createURL,
getApiRequestParams,
getServerSideParams,
useRouterWithSSR,
useRouterWithNoSSR,
} = createTypedFns([
// Here will be all your project routes:
"/",
"/api/auth/login",
"/api/projects/[projectId]",
"/projects",
"/projects/[projectId]",
"/users",
"/users/[userId]",
"/users/[userId]/favorites/[[...rest]]",
"/users/[userId]/repositories",
"/users/[userId]/repositories/[repositoryId]",
]);
```
## API
### createURL
```tsx
import Link from "next/link";
import { createURL } from "path/to/routes";
export default function ExamplePage() {
return (
<>
Users
{/* URL params are type safe! */}
zoontek
>
);
}
```
### useRouterWithSSR
```tsx
import { useRouterWithSSR } from "path/to/routes";
export default function ExamplePage() {
const { params } = useRouterWithSSR("/users/[userId]"); // we can use useRouterWithSSR since getServerSideProps is used
const { userId } = params.route; // userId type is string
return
{userId} profile
;
}
```
### useRouterWithNoSSR
```tsx
import { useRouterWithNoSSR } from "path/to/routes";
export default function ExamplePage() {
const { params } = useRouterWithNoSSR("/users/[userId]"); // we have to use useRouterWithNoSSR since getServerSideProps is not used
const { userId } = params.route; // userId type is string | undefined
if (userId == null) {
return Loading…;
}
return
{userId} profile
;
}
```
### getApiRequestParams
```ts
import type { NextApiRequest, NextApiResponse } from "next";
import { getApiRequestParams } from "path/to/routes";
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// we can access params in a safe way on API routes
const params = getApiRequestParams("/api/projects/[projectId]", req);
res.status(200).json({ handler: "project", params });
}
```
### getServerSideParams
```ts
import { GetServerSideProps } from "next";
import Link from "next/link";
import { getServerSideParams } from "path/to/routes";
export const getServerSideProps: GetServerSideProps = async (context) => {
const params = getServerSideParams("/users/[userId]", context);
// we can access params in a safe way on the server
console.log(params.route.userId);
return { props: {} };
};
```
## Error handling
What happen when I, let's say, use `useRouterWithSSR("/users/[userId]")` in page with `/project/[projectId]` path?
Well, it will throw an error đź’Ą. That's why I **highly** recommend to create a [`500.tsx` page](https://nextjs.org/docs/advanced-features/custom-error-page#500-page) and wrap your app in an [Error Boundary](https://reactjs.org/docs/error-boundaries.html).
