Skip to contentSkip to navigationSkip to topbar
Paste assistant Assistant
Figma
Star

Wizard

A Wizard focuses customers through a series of tasks to reach a goal.


<Box display="flex" width="100%" justifyContent="center" paddingX="space10">
  <Box paddingTop="space130" paddingBottom="space160" width="size70" maxWidth="size80">
    <PageHeader>
      <PageHeaderSetting>
        <Breadcrumb aria-label={useUID()}>
          <BreadcrumbItem href="#">Breadcrumb</BreadcrumbItem>
          <BreadcrumbItem href="#">Breadcrumb</BreadcrumbItem>
          <BreadcrumbItem href="#">Breadcrumb</BreadcrumbItem>
        </Breadcrumb>
        <ProgressSteps>
          <ProgressStepCurrent as="div">Label</ProgressStepCurrent>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
        </ProgressSteps>
      </PageHeaderSetting>
      <PageHeaderDetails>
        <PageHeaderKeyword>Wizard title</PageHeaderKeyword>
        <PageHeaderHeading>Verb heading</PageHeaderHeading>
        <PageHeaderParagraph>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi non ex risus. Aenean at ante id lectus
          faucibus hendrerit a fringilla lorem. Pellentesque faucibus sit amet dolor vitae lacinia.
        </PageHeaderParagraph>
      </PageHeaderDetails>
    </PageHeader>
    <Box display="flex" flexDirection="column" rowGap="space130">
      <Box>
        <Form>
          <FormControl>
            <Label htmlFor={input1}>Label</Label>
            <Input type="text" id={input1} name="input1" />
          </FormControl>
          <FormControl>
            <Label htmlFor={input2}>Label</Label>
            <Input type="text" id={input2} name="input2" />
          </FormControl>
          <FormControl>
            <Label htmlFor={input3}>Label</Label>
            <Input type="text" id={input3} name="input3" />
          </FormControl>
          <FormControl>
            <Label htmlFor={input4}>Label</Label>
            <Input type="text" id={input4} name="input4" />
          </FormControl>
        </Form>
      </Box>
      <Box display="flex" justifyContent="end">
        <ButtonGroup>
          <Button variant="secondary">Cancel or Close</Button>
          <Button variant="primary">
            Next <ArrowForwardIcon decorative />
          </Button>
        </ButtonGroup>
      </Box>
    </Box>
  </Box>
</Box>

About Wizard

About Wizard page anchor

Use a Wizard when a customer’s goal is long or complex, and breaking it up into smaller page-by-page tasks allows the user to focus and not feel overwhelmed. A Wizard can be useful when the tasks to reach a goal are dependent on each other, and customers need to finish different tasks based on previous ones.

Start by splitting the goal across multiple tasks with each page containing just one main task, for example:

  • One piece of information the customer needs to know
  • One decision they have to make
  • One question they have to answer

A single task or page can still have multiple form fields or pieces of information if they’re related.

(information)

Looking for guidelines on multi-step flows contained to Modals or Cards?

We don’t have guidelines yet for multi-step flows that aren’t the only flow on a page. If you need it for your work, please consider partnering with us to contribute it.

How to use this template

How to use this template page anchor
<>
  <Sidebar
    variant="compact"
    collapsed={true}
    sidebarNavigationSkipLinkID={sidebarNavigationSkipLinkID}
    topbarSkipLinkID={topbarSkipLinkID}
    mainContentSkipLinkID={mainContentSkipLinkID}
    aria-label={sidebarId}
  >
    <div id={sidebarNavigationSkipLinkID} />
  </Sidebar>
  <SidebarPushContentWrapper collapsed={true} variant="compact">
    <Topbar id={topbarSkipLinkID}> </Topbar>
    <Box display="flex" width="100%" justifyContent="center" paddingX="space50" id={mainContentSkipLinkID}>
      <Box paddingTop="space130" paddingBottom="space160" width="size70" maxWidth="size80">
        <PageHeader>
          <PageHeaderDetails>
            <PageHeaderKeyword>Add Reverse ETL destination</PageHeaderKeyword>
            <PageHeaderHeading>Set up destination</PageHeaderHeading>
          </PageHeaderDetails>
        </PageHeader>
        <Box display="flex" flexDirection="column" rowGap="space130">
          <Box>
            <Form>
              <FormControl>
                <Label htmlFor={input1}>Destination name</Label>
                <Input type="text" id={input1} name="input1" />
                <HelpText>
                  Identifies this destination within your organization and typically includes the business unit,
                  geographic region, or environment. Example: Google Analytics North America Prod.
                </HelpText>
              </FormControl>
            </Form>
          </Box>
          <Box display="flex" justifyContent="space-between">
            <Button variant="secondary">
              <ArrowBackIcon decorative />
              Back
            </Button>
            <ButtonGroup>
              <Button variant="secondary">Cancel or Close</Button>
              <Button variant="primary">Create destination</Button>
            </ButtonGroup>
          </Box>
        </Box>
      </Box>
    </Box>
  </SidebarPushContentWrapper>
</>

Content structure

Content structure page anchor

Before deciding on a page layout, make a few content and experience decisions first. This includes:

  • Wizard title: Describes the overall goal the customer is trying to achieve. The title should start with a verb. Examples: “Upgrade”, “Build Track call”.
  • Task headings: For each page, the task heading describes the current task the customer is doing. Each heading should generally be in the format “[Verb][object]”. Examples: “Select computed trait”, “Connect to Whatsapp”.
  • Task content: Decide what content and components will help a customer finish each task.
  • Goal linearity and duration: Decide whether a customer can achieve the entire goal in one session. Decide whether they need to leave Twilio to finish a task and whether they need to wait for Twilio to do something before finishing the flow.

There are 3 standard max-widths for the content of each Wizard page. Based on the content you need for each task, start with the smallest max-width and size up as needed:

  1. size-70 (712px). If this is too small, use:
  2. size-100 (1024px). If this is too small, use:
  3. Full-width, with a max-width of size-70 for the Page Header.

Use the same max-width for each page of the Wizard if possible.

In most scenarios, you’ll take customers through a Wizard without having to change the Sidebar or Topbar.

<>
  <Sidebar
    variant="compact"
    collapsed={true}
    sidebarNavigationSkipLinkID={sidebarNavigationSkipLinkID}
    topbarSkipLinkID={topbarSkipLinkID}
    mainContentSkipLinkID={mainContentSkipLinkID}
    aria-label={sidebarId}
  >
    <div id={sidebarNavigationSkipLinkID} />
  </Sidebar>
  <SidebarPushContentWrapper collapsed={true} variant="compact">
    <Topbar id={topbarSkipLinkID}> </Topbar>
    <Box display="flex" width="100%" justifyContent="center" paddingX="space50" id={mainContentSkipLinkID}>
      <Box paddingTop="space130" paddingBottom="space160" width="size70" maxWidth="size80">
        <PageHeader>
          <PageHeaderDetails>
            <PageHeaderKeyword>Add Reverse ETL destination</PageHeaderKeyword>
            <PageHeaderHeading>Set up destination</PageHeaderHeading>
          </PageHeaderDetails>
        </PageHeader>
        <Box display="flex" flexDirection="column" rowGap="space130">
          <Box>
            <Form>
              <FormControl>
                <Label htmlFor={input1}>Destination name</Label>
                <Input type="text" id={input1} name="input1" />
                <HelpText>
                  Identifies this destination within your organization and typically includes the business unit,
                  geographic region, or environment. Example: Google Analytics North America Prod.
                </HelpText>
              </FormControl>
            </Form>
          </Box>
          <Box display="flex" justifyContent="space-between">
            <Button variant="secondary">
              <ArrowBackIcon decorative />
              Back
            </Button>
            <ButtonGroup>
              <Button variant="secondary">Cancel or Close</Button>
              <Button variant="primary">Create destination</Button>
            </ButtonGroup>
          </Box>
        </Box>
      </Box>
    </Box>
  </SidebarPushContentWrapper>
</>
Page header page anchor

At the top of each page of the Wizard, add:

Use the Form component to set spacing between form elements.

There may be cases where you need to show multiple tasks on the same page because customers need to reference them at the same time. If this is the case, use a Ordered Display List to group tasks.

<Box display="flex" width="100%" justifyContent="center" paddingX="space10">
  <Box paddingTop="space130" paddingBottom="space160" width="size70" maxWidth="size80">
    <PageHeader>
      <PageHeaderSetting>
        <ProgressSteps>
          <ProgressStepComplete as="div">Select warehouse type</ProgressStepComplete>
          <ProgressStepSeparator />
          <ProgressStepCurrent as="div">Connect warehouse</ProgressStepCurrent>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Set sync schedule</ProgressStepIncomplete>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Set selective sync</ProgressStepIncomplete>
        </ProgressSteps>
      </PageHeaderSetting>
      <PageHeaderDetails>
        <PageHeaderKeyword>Add warehouse</PageHeaderKeyword>
        <PageHeaderHeading>Connect Azure SQL data warehouse</PageHeaderHeading>
        <PageHeaderParagraph>
          Follow the steps below to start setting up Azure SQL data warehouse.
        </PageHeaderParagraph>
      </PageHeaderDetails>
    </PageHeader>
    <Box display="flex" flexDirection="column" rowGap="space130">
      <Box display="flex" flexDirection="column" rowGap="space130" role="list">
        <Form>
          <Box display="flex" role="listitem">
            <Box width="size10" flexShrink={0}>
              <Text
                as="span"
                color="colorTextWeak"
                fontWeight="fontWeightSemibold"
                fontSize="fontSize60"
                lineHeight="lineHeight60"
              >
                1
              </Text>
            </Box>
            <Box width="100%">
              <FormSection>
                <FormSectionHeading variant="heading30">Configure your AzureSQL database</FormSectionHeading>
                <FormSectionDescription>
                  Make sure you’re logging in with a user that has read and write permissions so that we can write
                  to your database. If you’re unsure on how to get started, view our documentation on Azure SQL data
                  warehouse.
                </FormSectionDescription>
              </FormSection>
            </Box>
          </Box>
          <Box display="flex" role="listitem">
            <Box width="size10" flexShrink={0}>
              <Text
                as="span"
                color="colorTextWeak"
                fontWeight="fontWeightSemibold"
                fontSize="fontSize60"
                lineHeight="lineHeight60"
              >
                2
              </Text>
            </Box>
            <Box width="100%">
              <FormSection>
                <FormSectionHeading variant="heading30">Name your schema</FormSectionHeading>
                <FormSectionDescription>
                  Pick a name to help you identify this space in the warehouse, or use the default name provided.
                  This can’t be changed once the warehouse is connected.
                </FormSectionDescription>
                <FormControl>
                  <Label htmlFor={input1} required>
                    Name
                  </Label>
                  <Input type="text" id={input1} name="input1" required value="vik_test" />
                </FormControl>
              </FormSection>
            </Box>
          </Box>
          <Box display="flex" role="listitem">
            <Box width="size10" flexShrink={0}>
              <Text
                as="span"
                color="colorTextWeak"
                fontWeight="fontWeightSemibold"
                fontSize="fontSize60"
                lineHeight="lineHeight60"
              >
                3
              </Text>
            </Box>
            <Box width="100%">
              <FormSection>
                <FormSectionHeading variant="heading30">Enter your credentials</FormSectionHeading>
                <FormSectionDescription>Copy and paste these credentials from AzureSQL.</FormSectionDescription>
                <FormControl>
                  <Label htmlFor={input2}>Server name</Label>
                  <Input type="text" id={input2} name="input2" />
                </FormControl>
                <FormControl>
                  <Label htmlFor={input3}>Database</Label>
                  <Input type="text" id={input3} name="input3" />
                </FormControl>
                <FormControl>
                  <Label htmlFor={input4}>User</Label>
                  <Input type="text" id={input4} name="input4" />
                </FormControl>
                <FormControl>
                  <Label htmlFor={input5}>Password</Label>
                  <Input type="text" id={input5} name="input5" />
                </FormControl>
              </FormSection>
            </Box>
          </Box>
          <Box display="flex" role="listitem">
            <Box width="size10" flexShrink={0}>
              <Text
                as="span"
                color="colorTextWeak"
                fontWeight="fontWeightSemibold"
                fontSize="fontSize60"
                lineHeight="lineHeight60"
              >
                4
              </Text>
            </Box>
            <Box width="100%">
              <FormSection>
                <FormSectionHeading variant="heading30" marginBottom="space0">
                  Test connection
                </FormSectionHeading>
                <Box>
                  <Button variant="primary">Test warehouse connection</Button>
                </Box>
              </FormSection>
            </Box>
          </Box>
        </Form>
      </Box>
      <Box>
        <Separator orientation="horizontal" />
        <Box
          display="flex"
          justifyContent="space-between"
          columnGap="space40"
          marginTop="space50"
          alignItems="center"
        >
          <Button variant="secondary">
            <ArrowBackIcon decorative />
            Back
          </Button>
          <Box display="flex" columnGap="space40" alignItems="center">
            <Paragraph marginBottom="space0">Test your warehouse connection first.</Paragraph>
            <Button variant="primary" disabled>
              Next <ArrowForwardIcon decorative />
            </Button>
          </Box>
        </Box>
      </Box>
    </Box>
  </Box>
</Box>
(information)

Looking for guidelines on progressive disclosures?

We don’t have guidelines yet for this part of Wizard. If you need it for your work, please consider partnering with us to contribute it.

Use these actions in the footer, starting from the right side of the page:

  • A primary, right-aligned next Button to let a customer move to the next task. The Button is right-aligned to signal that the flow is moving forward. If there are more tasks, use the word “Next” followed by ArrowForwardIcon. If the customer is on the last task, the Button should indicate they are finishing the goal, and not include the arrow icon.
  • A secondary, right-aligned Button with the word “Cancel” if customers can’t save their progress, or “Close” if they can. Follow the confirmation pattern for guidance on how to ask a customer to confirm that they want to leave a Wizard or save their progress.
  • A secondary, left-aligned back Button. If there were previous tasks, use the ArrowBackIcon followed by the word “Back”. If there are no previous tasks, don’t show the Button.

If the task contents don’t fill the width of the page body, use a Separator above the actions with a gap of space-50. However this should be used sparingly because in most cases your content should fill the width of the page body.

Don’t disable any footer Buttons unless it’s immediately obvious to customers why they’re disabled. Disabled Buttons aren’t focusable and don’t provide any information about why they’re disabled. Instead, show Buttons in their default state, then provide helpful error text after they’re pressed.

<Box
  display="flex"
  flexDirection="column"
  width="100%"
  maxWidth="size70"
  paddingY="space150"
  paddingX="space100"
  rowGap="space200"
  >
  <Box display="flex" width="100%" flexDirection="column" rowGap="space50">
    <Separator orientation="horizontal" />
    <Box display="flex" justifyContent="space-between">
      <Button variant="secondary">
        <ArrowBackIcon decorative />
        Back
      </Button>
      <ButtonGroup>
        <Button variant="secondary">Cancel or close</Button>
        <Button variant="primary">
          Next <ArrowForwardIcon decorative />
        </Button>
      </ButtonGroup>
    </Box>
  </Box>
  <Box>
    <Box display="flex" justifyContent="space-between">
      <Button variant="secondary">
        <ArrowBackIcon decorative />
        Back
      </Button>
      <Button variant="primary">
        Next <ArrowForwardIcon decorative />
      </Button>
    </Box>
  </Box>
</Box>
<Box paddingBottom="space50">
  <Topbar id={useUID()}>
    <TopbarActions justify="start">
      <Text as="span" fontWeight="fontWeightSemibold" fontSize="fontSize60">
        Entities: Add warehouse
      </Text>
    </TopbarActions>
    <TopbarActions justify="end">
      <Button variant="secondary">Cancel or close</Button>
    </TopbarActions>
  </Topbar>
  <Box width="100%" display="flex" justifyContent="center">
    <Box width="size70" marginTop="space130">
      <PageHeader>
        <PageHeaderDetails>
          <PageHeaderHeading>Add warehouse</PageHeaderHeading>
        </PageHeaderDetails>
      </PageHeader>
      <Box display="flex" flexDirection="column" rowGap="space130">
        <VisualPickerRadioGroup
          value={value}
          legend="Select warehouse type"
          onChange={(newValue) => {
            setValue(newValue);
          }}
          name="warehouse type"
        >
          <VisualPickerRadio labelText="Snowflake" value="snowflake">
            Snowflake
          </VisualPickerRadio>
          <VisualPickerRadio labelText="Redshift" value="redshift">
            Redshift
          </VisualPickerRadio>
          <VisualPickerRadio labelText="BigQuery" value="bigquery">
            BigQuery
          </VisualPickerRadio>
        </VisualPickerRadioGroup>
        <Box display="flex" justifyContent="flex-end">
          <ButtonGroup>
            <Button variant="secondary">Cancel or close</Button>
            <Button variant="primary">
              Next <ArrowForwardIcon decorative />
            </Button>
          </ButtonGroup>
        </Box>
      </Box>
    </Box>
  </Box>
</Box>

Use the full-page Wizard template when it’s absolutely critical that a customer remains focused to finish the task.

If your app allows it, load the Wizard without a Sidebar, and replace the content in the Topbar with:

  • The Wizard title as a left-aligned Heading
  • A secondary, right-aligned Button with the word “Cancel” if customers can’t save their progress, or “Close” if they can. Follow the confirmation pattern for guidance on how to ask a customer to confirm that they want to leave a Wizard or save their progress.

If your app doesn’t allow loading a page without the navigation frame, collapse the Sidebar and follow the default Wizard template.

At the top of the page, add the Task Heading and if needed, Paragraph text under the heading to explain the step.

Follow the default Wizard template.

Follow the default Wizard template, but don’t include a close button in the footer.

When to use Progress Steps

When to use Progress Steps page anchor

Only use Progress Steps when necessary. Some scenarios include when:

  • A customer needs to return to previous steps, especially across multiple sessions.
  • A goal takes a long time to finish.
  • A customer is trying a feature out or going through more of an exploratory flow. Progress Steps can help them understand if they want to complete the steps.

If the customer’s journey through a Wizard is relatively linear, continuous, and short, don’t use Progress Steps.

When in doubt, start by not using Progress Steps, and add it in once it’s clear the experience suffers without it.

(information)

Research insight

Research from GOV.UK showed that their users were actually getting confused and intimidated when seeing their progress indicator. They found that completion rates, time-to-completion, and total amount of online applications were unaffected after removing their progress bar from their services.

Match Progress Steps labels to task headings for each page. If you need to use Progress Steps and there’s forking logic in the flow, hide Progress Steps until there’s a single path forward, or make the step labels generic enough to cover all variants of a task.

With the default template

With the default template page anchor

Place Progress Steps above the Wizard title.

<Box display="flex" width="100%" justifyContent="center" paddingX="space10">
  <Box
    paddingTop="space130"
    paddingBottom="space160"
    display="flex"
    flexDirection="column"
    rowGap="space130"
    width="size70"
    maxWidth="size80"
  >
    <PageHeader>
      <PageHeaderSetting>
        <Breadcrumb aria-label={useUID()}>
          <BreadcrumbItem href="#">Breadcrumb</BreadcrumbItem>
          <BreadcrumbItem href="#">Breadcrumb</BreadcrumbItem>
          <BreadcrumbItem href="#">Breadcrumb</BreadcrumbItem>
        </Breadcrumb>
        <ProgressSteps>
          <ProgressStepCurrent as="div">Label</ProgressStepCurrent>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
          <ProgressStepSeparator />
          <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
        </ProgressSteps>
      </PageHeaderSetting>
      <PageHeaderDetails>
        <PageHeaderKeyword>Wizard title</PageHeaderKeyword>
        <PageHeaderHeading>Verb heading</PageHeaderHeading>
        <PageHeaderParagraph>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi non ex risus. Aenean at ante id lectus
          faucibus hendrerit a fringilla lorem. Pellentesque faucibus sit amet dolor vitae lacinia.
        </PageHeaderParagraph>
      </PageHeaderDetails>
    </PageHeader>
  </Box>
</Box>

With the full-page template

With the full-page template page anchor

Center Progress Steps in the Topbar.

<Box paddingBottom="space50">
  <Topbar id={useUID()}>
    <TopbarActions justify="start">
      <Text as="span" fontWeight="fontWeightSemibold" fontSize="fontSize60">
        Wizard title
      </Text>
    </TopbarActions>
    <TopbarActions justify="center">
      <ProgressSteps>
        <ProgressStepComplete as="div">Label</ProgressStepComplete>
        <ProgressStepSeparator />
        <ProgressStepCurrent as="div">Label</ProgressStepCurrent>
        <ProgressStepSeparator />
        <ProgressStepIncomplete as="div">Label</ProgressStepIncomplete>
      </ProgressSteps>
    </TopbarActions>
    <TopbarActions justify="end">
      <Button variant="secondary">Cancel or close</Button>
    </TopbarActions>
  </Topbar>
</Box>