Using the App Router
Foundation is mostly built on the Next.js Pages Router (src/pages), but it also supports the App Router (src/app). For general App Router setup with authentication (Server Actions, middleware, forms), see the blueprint-auth App Router guide. This page instead walks through Foundation's own App Router reference implementation.
Reference implementation: the demo onboarding wizard​
Foundation has a working App Router example at apps/foundation/src/app/demo-onboarding. It's a multi-step form wizard (quote → tariffs → details → review → success) built to prove out createNextWizard from @krakentech/blueprint-onboarding on the App Router, using Server Actions instead of an API route.
Layout​
app/demo-onboarding/layout.tsx wraps every step in the shared UIProvider and page chrome, the same role _app.tsx plays for the Pages Router.
Shared wizard config​
The wizard's steps, form types, and validation are split into three files under domains/onboarding/shared/utils, so isomorphic code never accidentally pulls in server-only APIs:
wizard-common.ts— form value types, enums, and (de)serialization for storing state in a cookie. Shared by both routers.wizard-app-router.ts— the App Router's step list and yup validation schemas. Client-safe (nonext/headers).wizard-app-router-server.ts— the App Router'sdemoWizardAppRouterinstance, built withcreateNextWizardfrom@krakentech/blueprint-onboarding/next-wizard/app-router. Server-only, becausecreateNextWizardreads/writes cookies vianext/headers.
A step page​
Each step folder has a page.tsx (server component) and a *Client.tsx (client component). quote/page.tsx shows the pattern:
export default async function QuotePage() {
const state = await demoWizardAppRouter.getCookieState();
async function submitStep(newState: DemoOnboardingState) {
"use server";
await demoWizardAppRouter.setCookieState({ state: newState });
}
return (
<QuoteClient
serializedState={demoWizardAppRouter.serializeState(state)}
submitStep={submitStep}
/>
);
}
The server component reads the wizard's cookie state and passes it down as serialized data, along with an inline Server Action for saving it back. QuoteClient.tsx is a "use client" component that renders the Formik form; on submit it calls submitStep (the Server Action) to persist state, then router.push to move to the next step client-side.
Later steps (details, review) use a standalone actions.ts file with a top-level "use server" Server Action instead of an inline one — either pattern works, use whichever reads more clearly for the page.
See also​
blueprint-authApp Router getting started for setting up auth (middleware, Server Functions, sessions) on the App Routerblueprint-authBuilding Forms tutorial for Server Action form patterns, including a Formik exampleblueprint-onboardingApp Router API reference for the fullcreateNextWizardconfigblueprint-onboardingApp Router code examples