@definitely-fine/nextjs
v0.1.1
Published
Next.js request and server action helpers for definitely-fine scenarios.
Maintainers
Readme
@definitely-fine/nextjs
@definitely-fine/nextjs connects definitely-fine scenario context to Next.js route handlers and server actions.
It reads a scenario id from a request header and runs server-side Next.js code inside the matching active scenario context.
Installation
pnpm add definitely-fine @definitely-fine/nextjsImportant
[!IMPORTANT] Do not leave scenario activation enabled in production by accident.
@definitely-fine/nextjswill activate scenario context whenever the request header is present. In production, pair this package withcreateRuntime({ enabled: false })in your core runtime, or avoid wrapping handlers and server actions there entirely.
Core runtime protection:
import { createRuntime } from "definitely-fine";
const runtime = createRuntime<DemoContract>({
enabled: process.env.NODE_ENV !== "production",
});Optional route-level guard:
import { withDefinitelyFineScenario } from "@definitely-fine/nextjs";
const postCounterResponse = async (_request: Request): Promise<Response> => {
return Response.json({ ok: true });
};
export const POST =
process.env.NODE_ENV === "production"
? postCounterResponse
: withDefinitelyFineScenario(postCounterResponse);What This Package Does
This package does not replace the core runtime. You still create your scenarios and wrapped runtime with definitely-fine.
Its job is narrower:
- define the scenario header name constant
- read that header from
RequestorHeaders - run a route handler or server action inside
runWithRuntimeScenarioContext()
flowchart LR
subgraph C[Client or browser process]
C1[request]
C2[x-definitely-fine-scenario-id header]
end
subgraph N[Next.js server process]
N1[@definitely-fine/nextjs wrapper]
N2[runWithRuntimeScenarioContext]
N3[definitely-fine runtime]
N4[wrapped app service or function]
end
subgraph S[Shared scenario storage]
S1[(persisted scenario JSON)]
end
C1 --> C2 --> N1
N1 --> N2 --> N3 --> N4
N3 -- load active scenario --> S1Route Handlers
Use withDefinitelyFineScenario() to wrap a route handler.
import { withDefinitelyFineScenario } from "@definitely-fine/nextjs";
import { incrementApiCounter } from "../lib/demo-runtime";
async function postCounterResponse(_request: Request): Promise<Response> {
return Response.json(incrementApiCounter());
}
export const POST = withDefinitelyFineScenario(postCounterResponse);If the request does not include the scenario header, the handler runs normally.
Server Actions
Use withDefinitelyFineServerAction() to wrap a server action.
"use server";
import { withDefinitelyFineServerAction } from "@definitely-fine/nextjs";
import {
incrementActionCounter,
type CounterResult,
} from "../lib/demo-runtime";
export const incrementCounterAction = withDefinitelyFineServerAction(
async function incrementCounterActionImplementation(
_previousState: CounterResult,
): Promise<CounterResult> {
return incrementActionCounter();
},
);Header Name
The default exported header constant is DEFINITELY_FINE_SCENARIO_HEADER.
import { DEFINITELY_FINE_SCENARIO_HEADER } from "@definitely-fine/nextjs";
const headers = {
[DEFINITELY_FINE_SCENARIO_HEADER]: "scenario-id",
};Typical Setup
- Create and save a scenario with
definitely-fine. - Wrap the relevant Next.js route handlers or server actions with this package.
- Send the scenario id in the request header.
- Let your core runtime wrappers decide which calls are intercepted.
For safety, production apps should normally disable the core runtime with enabled: false and optionally skip these wrappers entirely.
With Playwright
This package pairs naturally with @definitely-fine/playwright, which can create browser contexts that already include the scenario header.
