You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: document type-safe router labels and per-label userData typing
Add a "Type-safe router labels and `userData`" section to the TypeScript
projects guide explaining how to declare a route map and pass it as the
second type argument to a `createXRouter` factory for per-label `userData`
typing. Mirrored into the latest (3.17) docs snapshot for the patch release.
Copy file name to clipboardExpand all lines: docs/guides/typescript_project.mdx
+35Lines changed: 35 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,8 @@ title: TypeScript Projects
4
4
description: Stricter, safer, and better development experience
5
5
---
6
6
7
+
importApiLinkfrom'@site/src/components/ApiLink';
8
+
7
9
Crawlee is built with TypeScript, which means it provides the type definition directly in the package. This allows writing code with auto-completion for TypeScript and JavaScript code alike. Besides that, projects written in TypeScript can take advantage of compile-time type-checking and avoid many coding mistakes, while providing documentation for functions, parameters and return values. It will also help with refactoring a lot, and ensuring the least amount of bugs will sneak through.
8
10
9
11
## Setting up a TypeScript project
@@ -152,3 +154,36 @@ Let's wrap it up to. In addition to the scripts we described above, we also need
152
154
}
153
155
}
154
156
```
157
+
158
+
## Type-safe router labels and `userData`
159
+
160
+
When you structure a crawler with a <ApiLinkto="core/class/Router">`Router`</ApiLink>, each route handler reads `request.userData`. By default `userData` is loosely typed, so a typo in a label or a wrong `userData` property is only caught at runtime.
161
+
162
+
You can instead declare a **route map** — an `interface` (or `type`) that maps each label to the shape of `userData` expected for it — and pass it as the second type argument to a `createXRouter` factory (or <ApiLinkto="core/class/Router#create">`Router.create`</ApiLink>). Handlers then get `request.userData` typed per label, and unknown labels become a compile-time error:
// ❌ compile error: 'TYPO' is not a label declared in `Routes`
184
+
router.addHandler('TYPO', async () => {});
185
+
```
186
+
187
+
The default handler registered via `addDefaultHandler` receives the union of all declared `userData` shapes.
188
+
189
+
This is a compile-time-only feature with **no runtime cost**, and it is fully backwards compatible — omitting the route map keeps the original loose typing, and passing a plain `userData` shape (e.g. `createCheerioRouter<CheerioCrawlingContext, { token: string }>()`) still types every handler with that shape, exactly as before.
Copy file name to clipboardExpand all lines: website/versioned_docs/version-3.17/guides/typescript_project.mdx
+35Lines changed: 35 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,8 @@ title: TypeScript Projects
4
4
description: Stricter, safer, and better development experience
5
5
---
6
6
7
+
importApiLinkfrom'@site/src/components/ApiLink';
8
+
7
9
Crawlee is built with TypeScript, which means it provides the type definition directly in the package. This allows writing code with auto-completion for TypeScript and JavaScript code alike. Besides that, projects written in TypeScript can take advantage of compile-time type-checking and avoid many coding mistakes, while providing documentation for functions, parameters and return values. It will also help with refactoring a lot, and ensuring the least amount of bugs will sneak through.
8
10
9
11
## Setting up a TypeScript project
@@ -152,3 +154,36 @@ Let's wrap it up to. In addition to the scripts we described above, we also need
152
154
}
153
155
}
154
156
```
157
+
158
+
## Type-safe router labels and `userData`
159
+
160
+
When you structure a crawler with a <ApiLinkto="core/class/Router">`Router`</ApiLink>, each route handler reads `request.userData`. By default `userData` is loosely typed, so a typo in a label or a wrong `userData` property is only caught at runtime.
161
+
162
+
You can instead declare a **route map** — an `interface` (or `type`) that maps each label to the shape of `userData` expected for it — and pass it as the second type argument to a `createXRouter` factory (or <ApiLinkto="core/class/Router#create">`Router.create`</ApiLink>). Handlers then get `request.userData` typed per label, and unknown labels become a compile-time error:
// ❌ compile error: 'TYPO' is not a label declared in `Routes`
184
+
router.addHandler('TYPO', async () => {});
185
+
```
186
+
187
+
The default handler registered via `addDefaultHandler` receives the union of all declared `userData` shapes.
188
+
189
+
This is a compile-time-only feature with **no runtime cost**, and it is fully backwards compatible — omitting the route map keeps the original loose typing, and passing a plain `userData` shape (e.g. `createCheerioRouter<CheerioCrawlingContext, { token: string }>()`) still types every handler with that shape, exactly as before.
0 commit comments