⚠️ 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;