-
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
38 changed files
with
20,729 additions
and
9,834 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Dependencies | ||
/node_modules | ||
|
||
# Production | ||
/build | ||
|
||
# Generated files | ||
.docusaurus | ||
.cache-loader | ||
|
||
# Misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Basic implementation | ||
|
||
You can find a basic working implementation [here](https://next-safe-action.vercel.app/). | ||
|
||
If you want to explore the project, you can check out its source code [here](https://github.com/TheEdoRan/next-safe-action/tree/main/packages/example-app). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
sidebar_position: 5 | ||
--- | ||
|
||
# Examples |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
--- | ||
sidebar_position: 2 | ||
--- | ||
|
||
# Getting started | ||
|
||
:::note | ||
This is the documentation for the current version of the library (4.x.x). If you are looking for version 3.x.x or 2.x.x docs, please check out [README_v3](https://github.com/TheEdoRan/next-safe-action/blob/main/packages/next-safe-action/README_v3.md) or [README_v2](https://github.com/TheEdoRan/next-safe-action/blob/main/packages/next-safe-action/README_v2.md) from the GitHub repository. | ||
::: | ||
|
||
:::info Requirements | ||
- Next.js >= 13.4.2 | ||
- TypeScript >= 5.0.0 | ||
- Zod >= 3.0.0 | ||
::: | ||
|
||
**next-safe-action** provides a typesafe Server Actions implementation for Next.js's 13 App Router, using Zod. | ||
|
||
## Installation | ||
|
||
```bash npm2yarn | ||
npm i next-safe-action zod | ||
``` | ||
|
||
## Usage | ||
|
||
:::note | ||
Turning on any `experimental` features in Next.js will switch the used React version to experimental. | ||
::: | ||
|
||
### 1. Enable server actions in Next.js | ||
|
||
To be able to use server actions, you need to enable them in your Next.js configuration (next.config.js file in project's root directory): | ||
|
||
```javascript title="next.config.js" | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
experimental: { | ||
serverActions: true, // add this | ||
}, | ||
}; | ||
|
||
module.exports = nextConfig; | ||
``` | ||
|
||
### 2. Instantiate a new client | ||
|
||
You can create a new client with the following code: | ||
|
||
```typescript title="src/lib/safe-action.ts" | ||
import { createSafeActionClient } from "next-safe-action"; | ||
|
||
export const action = createSafeActionClient(); | ||
``` | ||
|
||
This is a basic client, without any options. If you want to explore the full set of options, check out the [safe action alient](/docs/safe-action-client) section. | ||
|
||
### 3. Define a new action | ||
|
||
This is how a safe action is created. Providing a Zod input schema to the function, we're sure that data that comes in is type safe and validated. | ||
The second argument of this function is an async function that receives parsed input, and defines what happens on the server when the action is called from the client. In short, this is your server code. It never runs on the client: | ||
|
||
```typescript title="src/app/login-action.ts" | ||
"use server"; // Don't forget to add this! | ||
|
||
import { z } from "zod"; | ||
import { action } from "@/lib/safe-action"; | ||
|
||
// This schema is used to validate input from client. | ||
const schema = z.object({ | ||
username: z.string().min(3).max(10), | ||
password: z.string().min(8).max(100), | ||
}); | ||
|
||
export const loginUser = action(schema, async ({ username, password }) => { | ||
if (username === "johndoe" && password === "123456") { | ||
return { | ||
success: "Successfully logged in", | ||
}; | ||
} | ||
|
||
return { failure: "Incorrect credentials" }; | ||
}); | ||
``` | ||
|
||
`action` returns a new function that can be called from the client. | ||
|
||
### 4. Pass the action from a Server Component to a Client Component | ||
|
||
To avoid getting unwanted bugs when revalidating data on the server, it is _strongly_ recommended to pass the action from a Server Component to a Client Component, like this: | ||
|
||
```tsx title="src/app/page.tsx" | ||
import Login from "./login"; | ||
import { loginUser } from "./login-action"; | ||
|
||
export default function Home() { | ||
return ( | ||
<Login loginUser={loginUser} /> | ||
); | ||
} | ||
``` | ||
|
||
### 5. Execute the action | ||
|
||
In this example, we're **directly** calling the Server Actions from a Client Component. The action is passed as a prop to the component, and we can infer its type by simply using `typeof`: | ||
|
||
```tsx title="src/app/login.tsx" | ||
"use client"; // this is a Client Component | ||
|
||
import type { loginUser } from "./login-action"; | ||
|
||
type Props = { | ||
loginUser: typeof loginUser; // infer typings with `typeof` | ||
} | ||
|
||
export default function Login({ loginUser }: Props) { | ||
return ( | ||
<button | ||
onClick={async () => { | ||
// Typesafe action called from client. | ||
const res = await loginUser({ username: "johndoe", password: "123456" }); | ||
|
||
// Result keys. | ||
const { data, validationError, serverError } = res; | ||
}}> | ||
Log in | ||
</button> | ||
); | ||
} | ||
``` | ||
|
||
You also can execute Server Actions with hooks, which are a more powerful way to handle mutations. For more information about these, check out the [`useAction`](/docs/usage-from-client/hooks/useaction) and [`useOptimisticAction`](/docs/usage-from-client/hooks/useoptimisticaction) hooks sections. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Introduction | ||
|
||
**next-safe-action** is a library that takes full advantage of the latest and greatest Next.js, React and TypeScript features, using Zod, to let you define **typesafe** Server Actions and call them from Client Components. | ||
|
||
## How does it work? | ||
|
||
GIF here. | ||
|
||
## Features | ||
- ✅ Pretty simple | ||
- ✅ End to end type safety | ||
- ✅ Context based clients (with middlewares) | ||
- ✅ Input validation using Zod | ||
- ✅ Direct or hook usage from client | ||
- ✅ Optimistic updates | ||
|
||
:::note | ||
Server Actions are still an experimental feature in React/Next.js. For more information, please check out the Next.js [Server Actions documentation page](https://nextjs.org/docs/app/api-reference/functions/server-actions). | ||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
sidebar_position: 7 | ||
--- | ||
|
||
# Migration from v3 to v4 |
9 changes: 9 additions & 0 deletions
9
packages/website/docs/safe-action-client/custom-server-error-handling.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
sidebar_position: 2 | ||
--- | ||
|
||
# Custom server error handling | ||
|
||
### `handleServerErrorLog` | ||
|
||
### `handleReturnedServerError` |
5 changes: 5 additions & 0 deletions
5
packages/website/docs/safe-action-client/defining-multiple-clients.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
sidebar_position: 3 | ||
--- | ||
|
||
# Defining multiple clients |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
sidebar_position: 4 | ||
--- | ||
|
||
# Safe action client |
5 changes: 5 additions & 0 deletions
5
packages/website/docs/safe-action-client/using-a-middleware.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# Using a middleware |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
sidebar_position: 6 | ||
--- | ||
|
||
# Types |
14 changes: 14 additions & 0 deletions
14
packages/website/docs/usage-from-client/action-result-object.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
sidebar_position: 4 | ||
--- | ||
|
||
# Action result object | ||
|
||
Here's how action result object is structured (all keys are optional): | ||
|
||
|
||
| Name | When | Value | | ||
|--------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| `data?` | Execution is successful. | What you returned in action's server code. | | ||
| `validationError?` | Some input values are invalid. | A partial `Record` of input schema keys as key, and `string[]` as value. Example: `{ email: ["Email is required."] }` | | ||
| `serverError?` | An error occurs during action's server code execution. | A `string` that by default is "Something went wrong while executing the operation" for every server error that occurs, but this is [configurable](/docs/safe-action-client/custom-server-error-handling#handlereturnedservererror) when instantiating a new client. | |
25 changes: 25 additions & 0 deletions
25
packages/website/docs/usage-from-client/direct-execution.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# 1. Direct execution | ||
|
||
The first way to execute Server Actions inside Client Components is by passing the action from a Server Component to a Client Component and directly calling it in a function. This method is the most simple one, but it can be useful in some cases, for example if you just need the action result inside an `onClick` or `onSubmit` handler, without overcomplicating things: | ||
|
||
```tsx | ||
export default function Login({ loginUser }: Props) { | ||
return ( | ||
<button | ||
onClick={async () => { | ||
const result = await loginUser({ username: "johndoe", password: "123456" }); | ||
// Result is scoped to this function. You can do something with it here. | ||
}}> | ||
Log in | ||
</button> | ||
); | ||
} | ||
``` | ||
|
||
### Action result object | ||
|
||
Every action you execute returns an object with the same structure. This is described in the [action result object](/docs/usage-from-client/action-result-object) section. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
sidebar_position: 3 | ||
--- | ||
|
||
# Callbacks |
Oops, something went wrong.