UNPKG

workflow

Version:

Workflow SDK - Build durable, resilient, and observable workflows

140 lines (105 loc) • 5 kB
--- title: withWorkflow description: Configure webpack/turbopack to transform workflow directives in Next.js. type: reference summary: Wrap your Next.js config with withWorkflow to enable workflow directive transformation. prerequisites: - /docs/getting-started/next --- Configures webpack/turbopack loaders to transform workflow code (`"use step"`/`"use workflow"` directives) ## Usage To enable `"use step"` and `"use workflow"` directives while developing locally or deploying to production, wrap your `nextConfig` with `withWorkflow`. ```typescript title="next.config.ts" lineNumbers import { withWorkflow } from "workflow/next"; // [!code highlight] import type { NextConfig } from "next"; const nextConfig: NextConfig = { // … rest of your Next.js config }; // not required but allows configuring workflow options const workflowConfig = {} export default withWorkflow(nextConfig, workflowConfig); // [!code highlight] ``` <Callout type="warn"> If a package in `serverExternalPackages` contains workflow code (`"use step"`, `"use workflow"`, or serialization classes), `withWorkflow()` automatically removes it from `serverExternalPackages` for the current build and prints a warning. Workflow still compiles the package so its directives are transformed. Remove that package from `serverExternalPackages` in your `next.config` to silence the warning. </Callout> ### Workflow Discovery in Next.js `withWorkflow()` discovers workflows by scanning your Next.js entrypoints — App Router `route`, `page`, and `layout` files (under `app/` or `src/app/`) and any file under `pages/` or `src/pages/` — for `start()` calls imported from `workflow/api`. The workflow and step files themselves can live anywhere (for example `src/workflows/`); they are discovered transitively through imports, as long as a `start()` call in an entrypoint statically reaches them. <Callout type="info"> Call `start()` from server-side entrypoints, including Route Handlers and Server Actions. Don't call workflow functions directly — that bypasses the workflow runtime. </Callout> ### Next.js Server Actions and `"use server"` Don't put a top-level `"use server"` directive in modules imported by workflow or step functions. Workflow transformation wraps imported modules in synchronous initializers, and Next.js rejects a `"use server"` directive inside that wrapper with errors like `Server Actions must be async functions`. Keep `"use server"` on the files that define your Server Actions, and move shared logic into separate modules that don't carry the directive. ### Monorepos and Workspace Imports By default, Next.js detects the correct workspace root automatically. If your Next.js app lives in a subdirectory such as `apps/web` and workspace resolution is not working correctly, you can set `outputFileTracingRoot` as a workaround: ```typescript title="apps/web/next.config.ts" lineNumbers import { resolve } from "node:path"; import type { NextConfig } from "next"; import { withWorkflow } from "workflow/next"; const nextConfig: NextConfig = { outputFileTracingRoot: resolve(process.cwd(), "../.."), }; export default withWorkflow(nextConfig); ``` <Callout type="info"> Use the smallest directory that contains every workspace package imported by your workflows. If your app already lives at the repository root, you do not need to set `outputFileTracingRoot`. </Callout> ## Options `withWorkflow` accepts an optional second argument to configure the Next.js integration. ```typescript title="next.config.ts" lineNumbers import type { NextConfig } from "next"; import { withWorkflow } from "workflow/next"; const nextConfig: NextConfig = {}; export default withWorkflow(nextConfig, { workflows: { local: { port: 4000, }, }, }); ``` | Option | Type | Default | Description | | --- | --- | --- | --- | | `workflows.local.port` | `number` | — | Overrides the `PORT` environment variable for local development. Has no effect when deployed to Vercel. | <Callout type="info"> The `workflows.local` options only affect local development. When deployed to Vercel, the runtime ignores `local` settings and uses the Vercel world automatically. </Callout> ## Exporting a Function If you are exporting a function in your `next.config` you will need to ensure you call the function returned from `withWorkflow`. ```typescript title="next.config.ts" lineNumbers import { NextConfig } from "next"; import { withWorkflow } from "workflow/next"; import createNextIntlPlugin from "next-intl/plugin"; const withNextIntl = createNextIntlPlugin(); export default async function config( phase: string, ctx: { defaultConfig: NextConfig } ): Promise<NextConfig> { let nextConfig: NextConfig | typeof config = {}; for (const configModifier of [withNextIntl, withWorkflow]) { nextConfig = configModifier(nextConfig); if (typeof nextConfig === "function") { nextConfig = await nextConfig(phase, ctx); } } return nextConfig; } ```