Skip to main content

⚠️ NOTE ⚠️: The next-wizard is still experimental and can be imported at the path '@krakentech/blueprint-onboarding/next-wizard'.

API reference

The Next Wizard is a set of utils which handle server side state persistence, submission validation and routing for journeys which span across multiple pages. Using the builder pattern, extensive type safety is provided. In contrast to the previous wizard, this one is specifically designed for NextJS SSR usage. By simply providing a set of utils, the usage is very flexible and can be adjusted to meet each projects needs.

The createNextWizard() builder function

There are multiple configuration options in the createNextWizard builder function of the wizard, which are explained in the following.

export const {
getCookieFormData,
setCookieFormData,
deleteCookieFormData,
deserializeFormValues,
getNextStep,
getPreviousStep,
getRedirectionDestination,
getRedirectionStep,
getStep,
getSteps,
getMainSteps,
serializeFormValues,
getIsStepUnlocked,
} = createNextWizard<typeof OnboardingStep, FormValues, SerializedFormValues>({
cookieName,
encryptionSecret,
setCookieFormDataApiHandlerRoute,
initialValues,
steps,
serializeFormValues,
deserializeFormValues,
});

cookieName

The name of the cookie that stores the form data. Ensure that this name is unique to avoid conflicts with other cookies.

encryptionSecret (optional)

The secret used to encrypt the form values in the cookie. If no secret is provided then the form values will not be encrypted.

NOTE: If the secret is changed then the getCookieFormData function will delete the cookie and return default values for the cookie data.

setCookieFormDataApiHandlerRoute

The path of the API handler which sets the cookie form data.

initialValues

The initial form values which are used to initialise the form values state. Please note that the values object should be flat and contain all step values.

steps

The steps define the step ordering and hierarchy. Each step requires a name as identifier and pathname for navigation.

Step hierarchy

To define substeps, use the parentName attribute to link child steps to a 'parent' step. Each child step must have a parent step as an entry point.

Here is an example of what a simple set of steps could look like where we only need to show the StepName.SupplyChildStep if we get a particular response from the user/api in StepName.Supply.

const stepsConfig = [
{
name: StepName.Supply,
pathname: '/onboarding/1-supply',
},
// Here an example of how a child step could be setup
{
name: StepName.SupplyChildStep,
parentName: StepName.Supply,
pathname: '/onboarding/1-supply/child-step',
},
{
name: StepName.TariffSelection,
pathname: '/onboarding/2-tariff-selection',
},
...
] as const satisfies WizardSteps<StepName>;

For more advanced use cases, you can also provide a function, which gets the form values as an input and returns a set of steps based on those values. For example, the steps could be based on a tariff choice.

const getStepsConfig = (formValues: FormValues) => {
if (formValues.tariffName === 'octo_basic') {
return stepsConfigA;
}
return stepsConfigB;
};

queryParams

Steps can optionally include a queryParams field that can either be static using a constant definition, or dynamic using a function definition.

// static query params
const steps = [
{
name: StepName.EditPersonalDetails,
pathname: '/onboarding/3-personal-details',
queryParams: {
edit: 'true',
},
...
}
] as const satisfies WizardSteps<StepName>;

// dynamic query params
const getSteps = (formValues: FormValues) => [
{
name: StepName.Supply,
pathname: '/onboarding/1-supply',
queryParams: {
affiliate: formValues.affiliateCode,
},
...
}
] as const satisfies WizardSteps<StepName>;

serializeFormValues / deserializeFormValues

The wizard requires a serializeFormValues function which translates the formValues object state into a format that can be stored (cookie) or transmitted (from the server to the client) and reconstructed with the deserializeFormValues function later. Please ensure that there are no undefined form values, since this will cause errors when returned by the getServerSideProps function. Instead, use null to represent the empty state of a form field.

The following example shows how to (de-)serialise date values.

import { parseISO } from 'date-fns';

type FormValues = {
// ...
birthday: Date | null;
};

// The serialised form values object is also typed to provide full type safety
type SerializedFormValues = Omit<FormValues, 'birthday'> & {
birthday: string | null;
};

const serializeFormValues = (values: FormValues): SerializedFormValues => {
return { ...values, birthday: values.birthday?.toISOString() ?? null };
};

const deserializeFormValues = (values: SerializedFormValues): FormValues => {
return {
...values,
birthday: values.birthday ? parseISO(values.birthday) : null,
};
};

If the values don't require serialisation, e.g., if only simple data types are used in the form, then simply return the values back directly. These functions were intentionally made non-optional, to enforce consistent patterns and keep the typing simple.

type FormValues = { ... };
type SerializedFormValues = FormValues;

const serializeFormValues = (values: FormValues): SerializedFormValues => values;
const deserializeFormValues = (values: SerializedFormValues): FormValues => values;