Skip to content

Commit b820d97

Browse files
committed
chore(website): wip migration guide
1 parent d3ff580 commit b820d97

File tree

6 files changed

+645
-466
lines changed

6 files changed

+645
-466
lines changed

website/docs/migrations/v7-to-v8.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
sidebar_position: 4
3+
description: Learn how to migrate from next-safe-action version 7 to version 8.
4+
sidebar_label: v7 to v8
5+
---
6+
7+
# Migration from v7 to v8
8+
9+
Version 8 introduces significant changes to the validation system, improves type safety for metadata, and fixes next/navigation behaviors.
10+
11+
## What's new?
12+
13+
### [BREAKING] Standard Schema support
14+
15+
The biggest change in v8 is the switch to [Standard Schema](https://github.com/standard-schema/standard-schema) for validation. This removes the need for external validation adapters and simplifies the API. You can find the supported libraries [here](https://github.com/standard-schema/standard-schema?tab=readme-ov-file#what-schema-libraries-implement-the-spec).
16+
17+
```typescript title="v7 - using Valibot"
18+
import { createSafeActionClient } from "next-safe-action";
19+
import { valibotAdapter } from "next-safe-action/adapters/valibot";
20+
21+
export const actionClient = createSafeActionClient({
22+
validationAdapter: valibotAdapter(),
23+
});
24+
```
25+
26+
```typescript title="v8 - using Standard Schema"
27+
import { createSafeActionClient } from "next-safe-action";
28+
29+
export const actionClient = createSafeActionClient();
30+
```
31+
32+
### Type-checked metadata
33+
34+
Metadata is now type-checked when passed to actions. So, now if you forget to pass the expected metadata, you will get a type error.
35+
36+
<video controls autoPlay loop muted width="320" height="240">
37+
<source src="/vid/metadata-v8.mp4"/>
38+
</video>
39+
40+
### Custom thrown validation error messages
41+
42+
A new `overrideErrorMessage` function has been added to the `throwValidationErrors` utility, allowing you to customize error messages:
43+
44+
```typescript
45+
import { throwValidationErrors, overrideErrorMessage } from "next-safe-action";
46+
47+
actionClient
48+
.inputSchema((s) => ({
49+
username: s.string().minLength(3)
50+
}))
51+
.action(async ({ parsedInput: { username } }) => {
52+
// Custom validation error with overridden message
53+
if (usernameExists(username)) {
54+
throwValidationErrors({
55+
username: overrideErrorMessage("This username is already taken")
56+
});
57+
}
58+
59+
// ...
60+
});
61+
```
62+
63+
### Navigation callbacks
64+
65+
A new `onNavigation` callback has been added to both actions and hooks, which is triggered when navigation functions from `next/navigation` are called in action execution:
66+
67+
```typescript
68+
import { useAction } from "next-safe-action/hooks";
69+
import { redirect } from "next/navigation";
70+
71+
// In the action definition
72+
const action = actionClient
73+
.inputSchema((s) => ({ id: s.string() }))
74+
.action(async ({ parsedInput: { id } }) => {
75+
// ... process data
76+
redirect(`/details/${id}`);
77+
});
78+
79+
// In the component
80+
const { execute } = useAction(action, {
81+
onNavigation: ({ type, destination }) => {
82+
console.log(`Navigation of type ${type} to ${destination}`);
83+
}
84+
});
85+
```
86+
87+
## BREAKING CHANGES
88+
89+
### Removal of validation adapters
90+
91+
All external validation library adapters have been removed in favor of the built-in Standard Schema. This means you need to migrate your validation schemas to Standard Schema syntax.
92+
93+
### `schema` method renamed to `inputSchema`
94+
95+
The `schema` method has been renamed to `inputSchema` to better reflect its purpose:
96+
97+
```typescript
98+
// v7
99+
actionClient.schema(/* ... */)
100+
101+
// v8
102+
actionClient.inputSchema(/* ... */)
103+
```
104+
105+
The `schema` method is deprecated and will be removed in a future version.
106+
107+
### Bind args validation errors now throw instead of returning
108+
109+
When using bind arguments with invalid data, errors are now thrown instead of being returned as part of the result object:
110+
111+
```typescript
112+
// v7
113+
const result = await action.bind(null, invalidBindArg)(input);
114+
if (result.validationErrors) {
115+
// Handle bind args validation errors
116+
}
117+
118+
// v8
119+
try {
120+
const result = await action.bind(null, invalidBindArg)(input);
121+
} catch (error) {
122+
// Bind args validation errors now throw
123+
}
124+
```
125+
126+
### Safe action result always defined
127+
128+
The result of action execution is now always defined, even when there are validation errors:
129+
130+
```typescript
131+
// v7
132+
const result = await action(input);
133+
if (result.data) {
134+
// Only access data if it exists
135+
}
136+
137+
// v8
138+
const result = await action(input);
139+
// result.data is always defined (unless there's a server error)
140+
```
141+
142+
### Removed `executeOnMount` functionality from hooks
143+
144+
The `executeOnMount` option has been removed from hooks:
145+
146+
```typescript
147+
// v7
148+
const { data } = useAction(action, {
149+
executeOnMount: true,
150+
initialInput: { name: "John" }
151+
});
152+
153+
// v8 - no longer supported
154+
// You should execute the action manually when the component mounts
155+
const { execute, data } = useAction(action);
156+
useEffect(() => {
157+
execute({ name: "John" });
158+
}, []);
159+
```
160+
161+
### Deprecated `useStateAction` hook
162+
163+
The `useStateAction` hook has been deprecated. Consider using the regular `useAction` hook instead.
164+
165+
## Improved error handling
166+
167+
Thrown errors in hooks now properly set the `hasErrored` status and trigger the `onError` callback:
168+
169+
```typescript
170+
const { execute, hasErrored } = useAction(action, {
171+
onError: (error) => {
172+
console.error("Action failed:", error);
173+
}
174+
});
175+
```
176+
177+
## Requirements
178+
179+
next-safe-action version 8 requires Next.js 14 and React 18.2.0 or later to work.
180+
181+
## What about v7?
182+
183+
You can still keep using version 7 and eventually upgrade to version 8. Note that version 7 is frozen and no new features will be released in the future for it. v7 documentation can still be found [here](https://v7.next-safe-action.dev).

website/docusaurus.config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ export default {
128128
},
129129
],
130130
},
131+
announcementBar: {
132+
id: "next-safe-action-v8",
133+
content:
134+
"next-safe-action v8 is now available! Check out the <a href='/docs/migrations/v7-to-v8'>migration guide</a> to learn how to update your code for v8.",
135+
backgroundColor: "#2B2B2B",
136+
textColor: "#fff",
137+
isCloseable: true,
138+
},
131139
prism: {
132140
additionalLanguages: ["typescript"],
133141
theme: themes.vsLight,

website/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
"@docusaurus/preset-classic": "3.7.0",
2020
"@docusaurus/remark-plugin-npm2yarn": "^3.7.0",
2121
"@mdx-js/react": "^3.1.0",
22-
"acorn": "8.14.0",
22+
"acorn": "8.14.1",
2323
"clsx": "^2.1.1",
24-
"lucide-react": "^0.474.0",
24+
"lucide-react": "^0.487.0",
2525
"prism-react-renderer": "^2.4.1",
2626
"react": "^19",
2727
"react-dom": "^19"
@@ -30,8 +30,8 @@
3030
"@docusaurus/module-type-aliases": "3.7.0",
3131
"@docusaurus/tsconfig": "^3.7.0",
3232
"@docusaurus/types": "^3.7.0",
33-
"autoprefixer": "^10.4.20",
34-
"postcss": "^8.5.1",
33+
"autoprefixer": "^10.4.21",
34+
"postcss": "^8.5.3",
3535
"postcss-nested": "^7.0.2",
3636
"tailwindcss": "^3",
3737
"tailwindcss-bg-patterns": "^0.3.0",

0 commit comments

Comments
 (0)