@workflow/next 4.0.1-beta.8 → 4.0.1

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/docs/next.mdx ADDED
@@ -0,0 +1,303 @@
1
+ ---
2
+ title: Next.js
3
+ description: This guide will walk through setting up your first workflow in a Next.js app. Along the way, you'll learn more about the concepts that are fundamental to using the Workflow SDK in your own projects.
4
+ type: guide
5
+ summary: Set up Workflow SDK in a Next.js app.
6
+ prerequisites:
7
+ - /docs/getting-started
8
+ related:
9
+ - /docs/api-reference/workflow-next
10
+ - /docs/deploying/world/vercel-world
11
+ ---
12
+
13
+ <Steps>
14
+
15
+ <Step>
16
+ ## Create Your Next.js Project
17
+
18
+ Start by creating a new Next.js project. This command will create a new directory named `my-workflow-app` and set up a Next.js project inside it.
19
+
20
+ ```bash
21
+ npm create next-app@latest my-workflow-app
22
+ ```
23
+
24
+ Enter the newly created directory:
25
+
26
+ ```bash
27
+ cd my-workflow-app
28
+ ```
29
+
30
+ ### Install `workflow`
31
+
32
+ ```package-install
33
+ npm i workflow
34
+ ```
35
+
36
+ ### Configure Next.js
37
+
38
+ Wrap your `next.config.ts` with `withWorkflow()`. This enables usage of the `"use workflow"` and `"use step"` directives.
39
+
40
+ ```typescript title="next.config.ts" lineNumbers
41
+ import { withWorkflow } from "workflow/next"; // [!code highlight]
42
+ import type { NextConfig } from "next";
43
+
44
+ const nextConfig: NextConfig = {
45
+ // … rest of your Next.js config
46
+ };
47
+
48
+ export default withWorkflow(nextConfig); // [!code highlight]
49
+ ```
50
+
51
+ <Accordion type="single" collapsible>
52
+ <AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
53
+ <AccordionTrigger className="text-sm">
54
+ ### Setup IntelliSense for TypeScript (Optional)
55
+ </AccordionTrigger>
56
+ <AccordionContent className="[&_p]:my-2">
57
+
58
+ To enable helpful hints in your IDE, setup the workflow plugin in `tsconfig.json`:
59
+
60
+ ```json title="tsconfig.json" lineNumbers
61
+ {
62
+ "compilerOptions": {
63
+ // ... rest of your TypeScript config
64
+ "plugins": [
65
+ {
66
+ "name": "workflow" // [!code highlight]
67
+ }
68
+ ]
69
+ }
70
+ }
71
+ ```
72
+
73
+ </AccordionContent>
74
+ </AccordionItem>
75
+ </Accordion>
76
+
77
+ <Accordion type="single" collapsible>
78
+ <AccordionItem value="typescript-intellisense" className="[&_h3]:my-0">
79
+ <AccordionTrigger className="text-sm">
80
+ ### Configure Proxy Handler (if applicable)
81
+ </AccordionTrigger>
82
+ <AccordionContent className="[&_p]:my-2">
83
+
84
+ If your Next.js app has a [proxy handler](https://nextjs.org/docs/app/api-reference/file-conventions/proxy)
85
+ (formerly known as "middleware"), you'll need to update the matcher pattern to exclude Workflow's
86
+ internal paths to prevent the proxy handler from running on them.
87
+
88
+ Add `.well-known/workflow/*` to your middleware's exclusion list:
89
+
90
+ ```typescript title="proxy.ts" lineNumbers
91
+ import { NextResponse } from "next/server";
92
+ import type { NextRequest } from "next/server";
93
+
94
+ export function proxy(request: NextRequest) {
95
+ // Your middleware logic
96
+ return NextResponse.next();
97
+ }
98
+
99
+ export const config = {
100
+ matcher: [
101
+ // ... your existing matchers
102
+ {
103
+ source: "/((?!_next/static|_next/image|favicon.ico|.well-known/workflow/).*)", // [!code highlight]
104
+ },
105
+ ],
106
+ };
107
+ ```
108
+
109
+ This ensures that internal Workflow paths are not intercepted by your middleware, which could interfere with workflow execution and resumption.
110
+ </AccordionContent>
111
+ </AccordionItem>
112
+ </Accordion>
113
+
114
+ </Step>
115
+
116
+ <Step>
117
+
118
+ ## Create Your First Workflow
119
+
120
+ Create a new file for our first workflow:
121
+
122
+ ```typescript title="workflows/user-signup.ts" lineNumbers
123
+ import { sleep } from "workflow";
124
+
125
+ export async function handleUserSignup(email: string) {
126
+ "use workflow"; // [!code highlight]
127
+
128
+ const user = await createUser(email);
129
+ await sendWelcomeEmail(user);
130
+
131
+ await sleep("5s"); // Pause for 5s - doesn't consume any resources
132
+ await sendOnboardingEmail(user);
133
+
134
+ console.log("Workflow is complete! Run 'npx workflow web' to inspect your run")
135
+
136
+ return { userId: user.id, status: "onboarded" };
137
+ }
138
+
139
+ ```
140
+
141
+ We'll fill in those functions next, but let's take a look at this code:
142
+
143
+ * We define a **workflow** function with the directive `"use workflow"`. Think of the workflow function as the _orchestrator_ of individual **steps**.
144
+ * The Workflow SDK's `sleep` function allows us to suspend execution of the workflow without using up any resources. A sleep can be a few seconds, hours, days, or even months long.
145
+
146
+ ## Create Your Workflow Steps
147
+
148
+ Let's now define those missing functions.
149
+
150
+ ```typescript title="workflows/user-signup.ts" lineNumbers
151
+ import { FatalError } from "workflow"
152
+
153
+ // Our workflow function defined earlier
154
+
155
+ async function createUser(email: string) {
156
+ "use step"; // [!code highlight]
157
+
158
+ console.log(`Creating user with email: ${email}`);
159
+
160
+ // Full Node.js access - database calls, APIs, etc.
161
+ return { id: crypto.randomUUID(), email };
162
+ }
163
+
164
+ async function sendWelcomeEmail(user: { id: string; email: string; }) {
165
+ "use step"; // [!code highlight]
166
+
167
+ console.log(`Sending welcome email to user: ${user.id}`);
168
+
169
+ if (Math.random() < 0.3) {
170
+ // By default, steps will be retried for unhandled errors
171
+ throw new Error("Retryable!");
172
+ }
173
+ }
174
+
175
+ async function sendOnboardingEmail(user: { id: string; email: string}) {
176
+ "use step"; // [!code highlight]
177
+
178
+ if (!user.email.includes("@")) {
179
+ // To skip retrying, throw a FatalError instead
180
+ throw new FatalError("Invalid Email");
181
+ }
182
+
183
+ console.log(`Sending onboarding email to user: ${user.id}`);
184
+ }
185
+ ```
186
+
187
+ Taking a look at this code:
188
+
189
+ * Business logic lives inside **steps**. When a step is invoked inside a **workflow**, it gets enqueued to run on a separate request while the workflow is suspended, just like `sleep`.
190
+ * If a step throws an error, like in `sendWelcomeEmail`, the step will automatically be retried until it succeeds (or hits the step's max retry count).
191
+ * Steps can throw a `FatalError` if an error is intentional and should not be retried.
192
+
193
+ <Callout>
194
+ We'll dive deeper into workflows, steps, and other ways to suspend or handle events in [Foundations](/docs/foundations).
195
+ </Callout>
196
+
197
+ </Step>
198
+
199
+ <Step>
200
+
201
+ ## Create Your Route Handler
202
+
203
+ To invoke your new workflow, we'll need to add your workflow to a `POST` API Route Handler, `app/api/signup/route.ts`, with the following code:
204
+
205
+ ```typescript title="app/api/signup/route.ts"
206
+ import { start } from "workflow/api";
207
+ import { handleUserSignup } from "@/workflows/user-signup";
208
+ import { NextResponse } from "next/server";
209
+
210
+ export async function POST(request: Request) {
211
+ const { email } = await request.json();
212
+
213
+ // Executes asynchronously and doesn't block your app
214
+ await start(handleUserSignup, [email]);
215
+
216
+ return NextResponse.json({
217
+ message: "User signup workflow started",
218
+ });
219
+ }
220
+ ```
221
+
222
+ This Route Handler creates a `POST` request endpoint at `/api/signup` that will trigger your workflow.
223
+
224
+ <Callout>
225
+ Workflows can be triggered from API routes, Server Actions, or any server-side code.
226
+ </Callout>
227
+
228
+ </Step>
229
+
230
+ </Steps>
231
+
232
+ ## Run in development
233
+
234
+ To start your development server, run the following command in your terminal in the Next.js root directory:
235
+
236
+ ```bash
237
+ npm run dev
238
+ ```
239
+
240
+ Once your development server is running, you can trigger your workflow by running this command in the terminal:
241
+
242
+ ```bash
243
+ curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup
244
+ ```
245
+
246
+ Check the Next.js development server logs to see your workflow execute, as well as the steps that are being processed.
247
+
248
+ Additionally, you can use the [Workflow SDK CLI or Web UI](/docs/observability) to inspect your workflow runs and steps in detail.
249
+
250
+ ```bash
251
+ # Open the observability Web UI
252
+ npx workflow web
253
+ # or if you prefer a terminal interface, use the CLI inspect command
254
+ npx workflow inspect runs
255
+ ```
256
+
257
+ ![Workflow SDK Web UI](/o11y-ui.png)
258
+
259
+ ## Deploying to production
260
+
261
+ Workflow SDK apps currently work best when deployed to [Vercel](https://vercel.com/home) and need no special configuration.
262
+
263
+ <FluidComputeCallout />
264
+
265
+ Check the [Deploying](/docs/deploying) section to learn how your workflows can be deployed elsewhere.
266
+
267
+ ## Troubleshooting
268
+
269
+ ### Next.js 16.1+ compatibility
270
+
271
+ If you see this error when upgrading to Next.js 16.1 or later:
272
+
273
+ ```
274
+ Build error occurred
275
+ Error: Cannot find module 'next/dist/lib/server-external-packages.json'
276
+ ```
277
+
278
+ Upgrade to `workflow@4.2.0` or later:
279
+
280
+ ```package-install
281
+ workflow@latest
282
+ ```
283
+
284
+ ### `start()` says it received an invalid workflow function
285
+
286
+ If you see this error:
287
+
288
+ ```
289
+ 'start' received an invalid workflow function. Ensure the Workflow Development Kit is configured correctly and the function includes a 'use workflow' directive.
290
+ ```
291
+
292
+ Check both of these first:
293
+
294
+ 1. The workflow function includes `"use workflow"`.
295
+ 2. Your `next.config.ts` is wrapped with [`withWorkflow()`](/docs/api-reference/workflow-next/with-workflow).
296
+
297
+ See [start-invalid-workflow-function](/docs/errors/start-invalid-workflow-function) for full examples and fixes.
298
+
299
+ ## Next Steps
300
+
301
+ * Learn more about the [Foundations](/docs/foundations).
302
+ * Check [Errors](/docs/errors) if you encounter issues.
303
+ * Explore the [API Reference](/docs/api-reference).
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@workflow/next",
3
- "version": "4.0.1-beta.8",
4
- "description": "Next.js integration for Workflow DevKit",
3
+ "version": "4.0.1",
4
+ "description": "Next.js integration for Workflow SDK",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",
7
7
  "files": [
8
- "dist"
8
+ "dist",
9
+ "docs/**/*"
9
10
  ],
11
+ "directories": {
12
+ "doc": "./docs"
13
+ },
10
14
  "publishConfig": {
11
15
  "access": "public"
12
16
  },
@@ -22,19 +26,19 @@
22
26
  "./runtime": "./dist/runtime.js"
23
27
  },
24
28
  "dependencies": {
25
- "@swc/core": "1.11.24",
26
- "semver": "7.7.3",
27
- "watchpack": "2.4.4",
28
- "@workflow/builders": "4.0.1-beta.4",
29
- "@workflow/core": "4.0.1-beta.7",
30
- "@workflow/swc-plugin": "4.0.1-beta.2"
29
+ "@swc/core": "1.15.3",
30
+ "semver": "7.7.4",
31
+ "watchpack": "2.5.1",
32
+ "@workflow/builders": "4.0.1",
33
+ "@workflow/core": "4.2.0",
34
+ "@workflow/swc-plugin": "4.1.0"
31
35
  },
32
36
  "devDependencies": {
33
37
  "@types/node": "22.19.0",
34
38
  "@types/semver": "7.7.1",
35
39
  "@types/watchpack": "2.4.4",
36
- "next": "16.0.1",
37
- "@workflow/tsconfig": "4.0.1-beta.0"
40
+ "next": "16.2.1",
41
+ "@workflow/tsconfig": "4.0.1"
38
42
  },
39
43
  "peerDependencies": {
40
44
  "next": ">13"
@@ -47,6 +51,6 @@
47
51
  "scripts": {
48
52
  "build": "tsc",
49
53
  "dev": "tsc --watch",
50
- "clean": "tsc --build --clean && rm -rf dist"
54
+ "clean": "tsc --build --clean && rm -rf dist docs"
51
55
  }
52
56
  }