> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Confirmation - Web

A crucial safety net for users. Confirmation messages let users double-check actions (especially irreversible ones) and set expectations for what happens next.

![Example of confirmation message pattern in
action](https://mintcdn.com/servicetitan/UmHUvEuYrbSv6t_f/images/docs/web/patterns/shared/example-of-confirmation-message-pattern-in-action.png?fit=max\&auto=format\&n=UmHUvEuYrbSv6t_f\&q=85\&s=66ab549c7a5af44206362aca00994efa)

## Content Guidelines

For all confirmation messages, please refer to the [Confirmation Messages content pattern](https://anvil.servicetitan.com/docs/foundations/content/confirmation-messages.md) for content guidelines and tips for structuring messages.

## Unsaved Changes

An "unsaved changes" confirmation pattern is typically used when the user has made changes to data or content within the current workflow but attempts to navigate away without saving those changes. This pattern helps improve the user experience and prevents data loss or mistakes.

This pattern should not be used if no changes have been made by the user.

confirmation-unsaved

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-unsaved?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "14rem" }}>
      <Dialog open>
        <Dialog.Header>Discard unsaved changes?</Dialog.Header>
        <Dialog.Content>
          [Add description as needed...] This cannot be undone.
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="danger">Discard Changes</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

## Confirm an action

### Destructive

Use this pattern for confirming a destructive action, such as delete, disconnect, remove, disable, etc.

#### Simple Destructive Confirmation

Use when content is simple and text-only.

confirmation-destructive-simple

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-simple?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "12.5rem" }}>
      <Dialog open>
        <Dialog.Header>[Action][Item]</Dialog.Header>
        <Dialog.Content>Dialog text for a description.</Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="danger">[Action][Item]</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

##### Dos/Don'ts

confirmation-destructive-simple-do

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-simple-do?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "14rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Merge GL accounts?</Dialog.Header>
        <Dialog.Content>
          2 GL accounts will be merged into the following account: Inventory.
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="danger">Merge GL Accounts</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!TIP]
>
> **Do**

confirmation-destructive-simple-dont-01

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-simple-dont-01?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "14rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Delete Profile?</Dialog.Header>
        <Dialog.Content>
          Are you sure you want to delete this profile? This action cannot be
          undone.
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="danger">Confirm</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!CAUTION]
>
> **Don't**

confirmation-destructive-simple-dont-02

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-simple-dont-02?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "14rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Remove Activity</Dialog.Header>
        <Dialog.Content>
          Are you sure you want to remove Travel AM activity?
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="primary">Confirm</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!CAUTION]
>
> **Don't**

* Use question format for title
* Ask the question in title, not description. Don’t phrase it as “Are you sure you want to...?”
* Use negative color for destructive action
* Match the CTA label with the title (e.g., "Delete Profile")

#### Complex Destructive Confirmation

This pattern is used in contexts where the content of the Dialog is more complex (e.g., long description, bullet points, multiple paragraphs, etc.).

confirmation-destructive-complex

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-complex?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button, Text, Combobox } from "@servicetitan/anvil2";
import { useState } from "react";

type Item = {
  id: number;
  name: string;
};

const items: Item[] = [
  { id: 1, name: "First item" },
  { id: 2, name: "Second item" },
  { id: 3, name: "Third item" },
  { id: 4, name: "Fourth item" },
  { id: 5, name: "Fifth item" },
  { id: 6, name: "Sixth item" },
  { id: 7, name: "Seventh item" },
  { id: 8, name: "Eighth item" },
  { id: 9, name: "Ninth item" },
  { id: 10, name: "Tenth item" },
];

function App() {
  const [selectedItem, setSelectedItem] = useState<Item | null>();

  return (
    <div style={{ minWidth: "23rem", minHeight: "23.5rem" }}>
      <Dialog open>
        <Dialog.Header>[Action][Item]</Dialog.Header>
        <Dialog.Content>
          <Flex direction="column" gap="2" style={{ width: "100%" }}>
            <Text variant="body" size="medium">
              Description
            </Text>
            <ul>
              <li>Description...</li>
              <li>Description...</li>
              <li>Description...</li>
            </ul>
            <Combobox
              items={items}
              itemToString={(item) => (item ? item.name : "")}
              itemToKey={(item) => (item ? item.id : null)}
              selectedItem={selectedItem}
              onChange={setSelectedItem}
              filterOptions={{ keys: ["name"] }}
              style={{ width: "100%", maxWidth: "100%" }}
            >
              <Combobox.SearchField label="Select an item" />
              <Combobox.Content>
                {({ items }) => (
                  <Combobox.List>
                    {items.map((item, i) => (
                      <Combobox.Item key={item.id} item={item} index={i}>
                        {item.name}
                      </Combobox.Item>
                    ))}
                  </Combobox.List>
                )}
              </Combobox.Content>
            </Combobox>
          </Flex>
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="danger">[Action][Item]</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

##### Dos/Don'ts

confirmation-destructive-complex-do

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-complex-do?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button, Text, TextField } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "19rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Merge GL accounts?</Dialog.Header>
        <Dialog.Content>
          <Flex direction="column" gap="2">
            <Text>
              2 GL accounts will be merged into the following account: Inventory
            </Text>
            <TextField hint="Type MERGE to confirm" required />
          </Flex>
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="danger">Merge GL Accounts</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!TIP]
>
> **Do**

confirmation-destructive-complex-dont

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-complex-dont?file=src/App.tsx)

```tsx lines theme={null}
import { Popover, Flex, Button, Text, TextField } from "@servicetitan/anvil2";

function App() {
  return (
    <Flex gap="2">
      <Button>Back</Button>
      <Popover open placement="top" disableShift disableFlip modal>
        <Popover.Button appearance="primary">Merge</Popover.Button>
        <Popover.Content>
          <Flex
            direction="column"
            gap="2"
            style={{ width: "200px", maxWidth: "100%" }}
          >
            <Text
              variant="headline"
              size="small"
              el="h4"
              style={{ color: "red" }}
            >
              Merge GL Accounts
            </Text>
            <Text>
              This will merge 2 GL accounts into the following account:
              Inventory.
            </Text>
            <Text>Type ‘Merge’ to confirm action</Text>
            <TextField />
          </Flex>
        </Popover.Content>
      </Popover>
    </Flex>
  );
}

export default App;
```

> [!CAUTION]
>
> **Don't**

* Do not use a Popover for complex confirmation patterns as it has potential usability issues
* Use a danger Button instead of colored text

##### Edge Case

confirmation-destructive-edgecase-do

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-destructive-edgecase-do?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button, Combobox } from "@servicetitan/anvil2";
import { useState } from "react";

type Item = {
  id: number;
  name: string;
};

const items: Item[] = [
  { id: 1, name: "First item" },
  { id: 2, name: "Second item" },
  { id: 3, name: "Third item" },
  { id: 4, name: "Fourth item" },
  { id: 5, name: "Fifth item" },
  { id: 6, name: "Sixth item" },
  { id: 7, name: "Seventh item" },
  { id: 8, name: "Eighth item" },
  { id: 9, name: "Ninth item" },
  { id: 10, name: "Tenth item" },
];

function App() {
  const [selectedItems, setSelectedItems] = useState<Item[] | null>([]);

  return (
    <div style={{ minWidth: "23rem", minHeight: "18rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Cancel Receipt?</Dialog.Header>
        <Dialog.Content>
          <Flex direction="column" gap="2">
            Select the reason why you are canceling this receipt.
            <Combobox
              multiple
              items={items}
              itemToString={(item) => (item ? item.name : "")}
              itemToKey={(item) => (item ? item.id : null)}
              selectedItems={selectedItems ?? []}
              onChange={setSelectedItems}
              filterOptions={{ keys: ["name"] }}
              style={{ width: "100%", maxWidth: "100%" }}
            >
              <Combobox.SearchField
                label="Select a reason"
                moreInfo="Please let us know why you are canceling"
              />
              <Combobox.Content>
                {({ items }) => (
                  <Combobox.List>
                    {items.map((item, i) => (
                      <Combobox.Item key={item.id} item={item} index={i}>
                        {item.name}
                      </Combobox.Item>
                    ))}
                  </Combobox.List>
                )}
              </Combobox.Content>
            </Combobox>
          </Flex>
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Don&apos;t Cancel</Dialog.CancelButton>
              <Button appearance="danger">Cancel Receipt</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!TIP]
>
> **Do**

* When the action itself contains the word “Cancel”, use a verb-noun pairing like "Cancel Receipt" in the CTA so users would know what happens if that's the only thing they read. Primary CTA should mirror the question in the header.
* Use "Don't Cancel" as the secondary action when the main CTA is "Cancel"

### Non-Destructive

Use this pattern when confirming a non-destructive action, such as activate, enable, continue, etc.

#### Simple Non-Destructive Confirmation

Use when content is simple and text-only.

confirmation-nondestructive-simple

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-nondestructive-simple?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "12.5rem" }}>
      <Dialog open>
        <Dialog.Header>[Action][Item]</Dialog.Header>
        <Dialog.Content>Dialog text for a description.</Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="primary">[Action][Item]</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

##### Dos/Don'ts

confirmation-nondestructive-simple-do

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-nondestructive-simple-do?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "14rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Activate campaign?</Dialog.Header>
        <Dialog.Content>
          The campaign will be immediately activated.
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="primary">Activate campaign</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!TIP]
>
> **Do**

confirmation-nondestructive-simple-dont-01

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-nondestructive-simple-dont-01?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "14rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Confirmation activation</Dialog.Header>
        <Dialog.Content>
          The campaign will be immediately activated.
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="danger">Confirm</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!CAUTION]
>
> **Don't**

confirmation-nondestructive-simple-dont-02

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-nondestructive-simple-dont-02?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "15rem" }}>
      <Dialog enableScrollChaining open>
        <Dialog.Header>Confirmation</Dialog.Header>
        <Dialog.Content>
          You are about to recalculate estimate tax using the actual
          configuration from zone 1 tax zone. Are you sure?
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="primary">Yes</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!CAUTION]
>
> **Don't**

* Use primary (blue) button for non-destructive action
* Avoid using yes/no, primary CTA should mirror the question in the header.
* If button text is too long and space is limited, prioritize retaining the verb and noun while omitting adjectives
  * For example, "Recalculate Estimate Tax" can be shortened to "Recalculate Tax."

#### Complex Non-Destructive Confirmation

Use this pattern when content contains UI elements beyond plain text (e.g., card, table, etc.).

confirmation-nondestructive-complex

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-nondestructive-complex?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button, Text } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "23rem", minHeight: "23.5rem" }}>
      <Dialog open>
        <Dialog.Header>[Action][Item]</Dialog.Header>
        <Dialog.Content>
          <Flex direction="column" gap="2" style={{ width: "100%" }}>
            <Flex
              justifyContent="center"
              style={{
                width: "100%",
                border: "1px solid #ccc",
                padding: "2rem",
              }}
            >
              <Text variant="eyebrow" size="small">
                image, table, banner, etc.
              </Text>
            </Flex>
            <Text variant="body" size="medium">
              Description
              <ul style={{ marginTop: "0" }}>
                <li>Description...</li>
                <li>Description...</li>
                <li>Description...</li>
              </ul>
            </Text>
          </Flex>
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="primary">[Action][Item]</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

##### Dos/Don'ts

confirmation-nondestructive-complex-do

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-nondestructive-complex-do?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button, Alert, Link, Text } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "35.5rem", minHeight: "30rem" }}>
      <Dialog enableScrollChaining open size="large">
        <Dialog.Header>Enable Autopilot?</Dialog.Header>
        <Dialog.Content>
          <Flex direction="column" gap="3">
            <Alert title="Note" status="warning" onClose={console.log}>
              If a 3rd party manages your digital ads, this will make changes to
              the bid strategy and could create confusion.{" "}
              <Link>Learn more</Link>
            </Alert>
            <Text>
              By enabling Autopilot, ServiceTitan will optimize your
              campaign&apos;s bid strategy to achieve the highest ROI. Please
              Click on “Enable Autopilot” if you wish to have ServiceTitan to
              run Autopilot.
            </Text>
            <Flex direction="column">
              <Text variant="eyebrow" size="small">
                Campaign
              </Text>
              <Text variant="headline" size="small" el="h4">
                Aging Equipment Memorial Day
              </Text>
              <Flex gap="3">
                <Text>Google Ads</Text>
                <Text>CPC</Text>
              </Flex>
            </Flex>
          </Flex>
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="primary">Enable Autopilot</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!TIP]
>
> **Do**

confirmation-nondestructive-complex-dont

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-nondestructive-complex-dont?file=src/App.tsx)

```tsx lines theme={null}
import { Dialog, Flex, Button, Alert, Link, Text } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ minWidth: "35.5rem", minHeight: "30rem" }}>
      <Dialog enableScrollChaining open size="large">
        <Dialog.Header>Autopilot</Dialog.Header>
        <Dialog.Content>
          <Flex direction="column" gap="3">
            <Text>
              By enabling Autopilot, ServiceTitan will optimize your campaign’s
              bid strategy to achieve the highest ROI. Please click on “Yes,
              Confirm” if you wish to have ServiceTitan to run Autopilot.
            </Text>
            <Flex direction="column">
              <Text variant="eyebrow" size="small">
                Campaign
              </Text>
              <Text variant="headline" size="small" el="h4">
                Aging Equipment Memorial Day
              </Text>
              <Flex gap="3">
                <Text>Google Ads</Text>
                <Text>CPC</Text>
              </Flex>
            </Flex>
            <Alert title="Note" status="warning" onClose={console.log}>
              If a 3rd party manages your digital ads, this will make changes to
              the bid strategy and could create confusion.{" "}
              <Link>Learn more</Link>
            </Alert>
          </Flex>
        </Dialog.Content>
        <Dialog.Footer>
          <Flex justifyContent="flex-end">
            <Flex gap="3">
              <Dialog.CancelButton>Cancel</Dialog.CancelButton>
              <Button appearance="primary">Yes, Confirm</Button>
            </Flex>
          </Flex>
        </Dialog.Footer>
      </Dialog>
    </div>
  );
}

export default App;
```

> [!CAUTION]
>
> **Don't**

* Use appropriate Dialog size according to content
* Alert should be displayed above content

## Congratulations/Success

A Congratulations/Success confirmation pattern is typically used when the user has successfully completed a task or workflow. The pattern helps improve the user experience by providing feedback to the user and can be an opportunity to delight the user.

#### Simple task

* Use when the user completed an easy, short, and common task (i.e., something that users do multiple times).
* The Toast appears after the task is completed and the page reloads.
* If the user navigated to a different page or Dialog to complete the task, the Toast appears after navigating the user to the page where they started the task.

![Success Toast
example](https://mintcdn.com/servicetitan/KE7wVYXA9MgEh_Ye/images/docs/web/patterns/confirmation/success-toast-example.png?fit=max\&auto=format\&n=KE7wVYXA9MgEh_Ye\&q=85\&s=248107217c0d591ccda9090fcd48e84f)

#### Complex task/workflow with no next steps

* Use when the user completed a more complex task or workflow and there are no next steps to complete. Note: The only CTA that should be used in this template is “Done”.
* Complex tasks and workflows are generally 3 or more steps, time intensive, and something the user does only once.
* Dialog appears after navigating the user back to the page where they started the task or workflow.

![Template example for complex success message with no next
steps](https://mintcdn.com/servicetitan/KE7wVYXA9MgEh_Ye/images/docs/web/patterns/confirmation/template-example-for-complex-success-message-with-no-next-steps.png?fit=max\&auto=format\&n=KE7wVYXA9MgEh_Ye\&q=85\&s=2fa37e79571edecc2d2c09bf6d76517a)

##### Dos/Don'ts

![Success Dialog complex example DO
A](https://mintcdn.com/servicetitan/KE7wVYXA9MgEh_Ye/images/docs/web/patterns/confirmation/success-dialog-complex-example-do-a.png?fit=max\&auto=format\&n=KE7wVYXA9MgEh_Ye\&q=85\&s=6b311e9007a077dd370c834ad5c061f9)

> [!TIP]
>
> **Do**

![Success Dialog DONT example
A](https://mintcdn.com/servicetitan/KE7wVYXA9MgEh_Ye/images/docs/web/patterns/confirmation/success-dialog-dont-example-a.png?fit=max\&auto=format\&n=KE7wVYXA9MgEh_Ye\&q=85\&s=341433421e460ccd24757298c34a7790)

> [!CAUTION]
>
> **Don't**

* Use sentence case for title.
* Include only one CTA – “Done”. Note: if you want to include other CTAs, use the next template.
* Don’t include CTAs that perform actions or navigate the user to other pages. The user should already have been navigated to the next logical page before this Dialog appears.

#### Complex task/workflow with related CTAs

Use this pattern for complex tasks or workflows (e.g., three or more steps, time-intensive, or one-time actions). These dialogs appear after navigating the user back to their starting page and offer next steps beyond "Done".

![Success FSD Do example
B](https://mintcdn.com/servicetitan/KE7wVYXA9MgEh_Ye/images/docs/web/patterns/confirmation/success-fsd-do-example-b.png?fit=max\&auto=format\&n=KE7wVYXA9MgEh_Ye\&q=85\&s=510e5b689f150f4333ff4a3e17cb4150)

> [!TIP]
>
> **Do**

* Use a single column layout within a full-screen Dialog
* Include clear titles, explanations, and CTAs for each next step. Use a verb + noun pair as the button text for CTAs, like “Book Call” or “View Progress”.
* Don’t use a CTA that navigates the user back to where they started as this adds an unnecessary click. Automatically navigate the user there when they complete the flow and use the previous template as a success message instead.

#### Success as part of page content

* Use when the success message needs to be persistent and becomes a part of the page content.
* Alert appears immediately after the task or workflow is completed.

confirmation-success

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-success?file=src/App.tsx)

```tsx lines theme={null}
import { Alert } from "@servicetitan/anvil2";

function App() {
  return (
    <Alert status="success" title="[Process] [action]" onClose={console.log}>
      [Details such as date and time, next steps, etc.]
    </Alert>
  );
}

export default App;
```

##### Dos/Don'ts

confirmation-success-do

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/confirmation-success-do?file=src/App.tsx)

```tsx lines theme={null}
import { EditCard, Flex, Text, Alert } from "@servicetitan/anvil2";

function App() {
  return (
    <EditCard flexGrow="1" headerText="Migration" state="complete">
      <Flex direction="column" gap="3">
        <Text variant="eyebrow" size="medium">
          Automatically create driving and working entries when dispatch and
          arrive are pressed.
        </Text>
        <Alert title="Successful Migration" status="success">
          Customer was successfully migrated on 10/12/2025, 09:30 PST
        </Alert>
      </Flex>
    </EditCard>
  );
}

export default App;
```

> [!TIP]
>
> **Do**

* Include the Alert inline in the layout.
* Use when the success state and/or data around the completion of the flow needs to be documented for future views of the page. Include dates and times in the copy when applicable.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.