> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Verified Domains on Web

> Learn how to manage verified and pending Organization domains in a unified table interface.

export const ReleaseStageNotice = ({feature, stage, plans, contact, terms}) => {
  const stageTextMap = {
    "beta": "Beta",
    "ea": "Early Access"
  };
  const stageText = stageTextMap[stage] || "a product release stage";
  const prsLink = "/docs/troubleshoot/product-lifecycle/product-release-stages";
  const linkify = (text, url) => {
    return <a href={url} target="_blank" rel="noreferrer" class="link">{text}</a>;
  };
  const includeDetails = (plans, contact, terms) => {
    const hasDetails = terms || plans || contact;
    if (!hasDetails) return null;
    return <span data-as="p">
            {plans && <>This feature is available for {linkify(`${plans} plans`, "https://auth0.com/pricing")}. </>}
            {contact && "To participate, contact " + contact + ". "}
            {terms && <>By using this feature, you agree to the applicable Free Trial terms in Okta's {linkify("Master Subscription Agreement", "https://www.okta.com/legal")}.</>}
        </span>;
  };
  return <Warning>
            <span data-as="p">
                <strong>The {feature} feature is in {linkify(stageText, prsLink)}.</strong>
            </span>

            {includeDetails(plans, contact, terms)}
        </Warning>;
};

export const ComponentLoader = props => {
  const themePref = window?.localStorage?.getItem?.("isDarkMode");
  const theme = themePref === "dark" || themePref === "light" ? themePref : window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
  const lang = {
    i18n: {
      currentLanguage: props.lang || "en-US"
    }
  };
  return <div style={{
    minHeight: "400px",
    marginTop: "40px",
    background: theme === "light" ? "rgb(var(--gray-950)/.03)" : "rgb(255 255 255/.1)",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    position: "relative",
    backgroundSize: "16px 16px",
    borderRadius: "10px",
    boxShadow: "0 1px 4px 0 rgba(16,30,54,0.04)",
    display: "flex",
    flexDirection: "column"
  }}>
      <div style={{
    minWidth: "320px",
    width: "96.5%",
    maxWidth: "1200px",
    margin: "12px 12px 0",
    background: theme === "light" ? "#ffffff" : "#101011",
    borderRadius: "10px",
    boxShadow: "0 2px 8px 0 rgba(16,30,54,0.04)",
    padding: "24px",
    minHeight: "400px"
  }} data-uc-component={props.componentSelector} data-uc-props={JSON.stringify(lang)}>
        <Spinner size={40} color="#8A94A6" style={{
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: "translate(-50%, -50%)",
    zIndex: 1
  }} />
      </div>
      <div style={{
    width: "100%",
    textAlign: "center",
    color: theme === "light" ? "#6B7280" : "ffffff",
    fontSize: "12px",
    marginTop: "8px",
    marginBottom: "8px",
    letterSpacing: "0.01em",
    fontWeight: 400
  }}>
        {props.componentPreviewText}
      </div>
    </div>;
};

export const Spinner = ({size = 40, color = "#8A94A6", style = {}}) => <div style={{
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  ...style
}} aria-label="Loading" role="status">
    <svg width={size} height={size} viewBox="0 0 50 50" style={{
  display: "block"
}}>
      <circle cx="25" cy="25" r="20" fill="none" stroke={color} strokeWidth="5" strokeDasharray="90 150" strokeLinecap="round">
        <animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s" repeatCount="indefinite" />
      </circle>
    </svg>
  </div>;

<ReleaseStageNotice feature="Auth0 Universal Components" stage="ea" terms="true" contact="Auth0 Support" />

The `DomainTable` component provides a unified interface for your customers to manage their Auth0 Organization's email domain. By verifying domain ownership, Organization administrators enable critical B2B features like [Home Realm Discovery (HRD)](/docs/authenticate/enterprise-connections/self-service-enterprise-configuration/manage-self-service-enterprise-configuration#email-domain-verification-and-pre-verified-domains) and ensure users are automatically routed to the correct SSO provider based on their email suffix (for example, `user@acme.com`).

<ComponentLoader componentSelector="domain-table-view" componentPreviewText="Preview of the Domain Table component" />

<Tabs>
  <Tab title="React">
    ## Setup requirements

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      **Auth0 Configuration Required**—Ensure your tenant is configured with the
      My Organization API. [View setup guide
      →](/docs/get-started/universal-components/web/components/build-delegated-admin#enable-the-my-organization-api)
    </Callout>

    ## Install the component

    <CodeGroup>
      ```bash pnpm  wrap lines theme={null}
      pnpm add @auth0/universal-components-react
      ```

      ```bash npm wrap lines theme={null}
      npm install @auth0/universal-components-react
      ```
    </CodeGroup>

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      Running either command also installs the @auth0/universal-components-core
      dependency for shared utilities and Auth0 integration.
    </Callout>

    ## Get started

    ```tsx React SPA wrap lines theme={null}
    import { DomainTable } from "@auth0/universal-components-react";

    export function DomainsPage() {
      return <DomainTable />;
    }
    ```

    <Accordion title="Full integration example">
      ```tsx wrap lines theme={null}
      import React from "react";
      import { DomainTable } from "@auth0/universal-components-react";
      import { Auth0Provider } from "@auth0/auth0-react";
      import { Auth0ComponentProvider } from "@auth0/universal-components-react/spa";
      import { useNavigate } from "react-router-dom";

      function DomainsManagementPage() {
        const navigate = useNavigate();

        return (
          <div className="max-w-6xl mx-auto p-6">
            <DomainTable
              schema={{
                create: {
                  domain: {
                    regex: /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i,
                    errorMessage: "Please enter a valid domain (e.g., example.com)",
                  },
                },
              }}
              createAction={{
                onBefore: (domain) => {
                  if (!domain.domain.includes(".")) {
                    alert("Please enter a valid domain with a TLD");
                    return false;
                  }
                  return true;
                },
                onAfter: (domain) => console.log("Domain created:", domain),
              }}
              verifyAction={{
                onAfter: (domain) => {
                  console.log("Domain verified:", domain.domain);
                },
              }}
              deleteAction={{
                onBefore: (domain) => {
                  return confirm(`Delete ${domain.domain}?`);
                },
              }}
              onOpenProvider={(provider) => {
                navigate(`/providers/${provider.id}`);
              }}
              onCreateProvider={() => {
                navigate("/providers/create");
              }}
              customMessages={{
                header: {
                  title: "Domain Management",
                  description: "Add and verify domains for your organization",
                  create_button_text: "Add New Domain",
                },
              }}
              styling={{
                variables: {
                  common: { "--font-size-label": "12px" },
                  light: { "--color-primary": "#0066cc" },
                },
                classes: {
                  "DomainTable-header": "shadow-lg rounded-xl",
                },
              }}
            />
          </div>
        );
      }

      export default function App() {
        const domain = "your-domain.auth0.com";

        return (
          <Auth0Provider
            domain={domain}
            clientId="your-client-id"
            authorizationParams={{
              redirect_uri: window.location.origin,
            }}
            interactiveErrorHandler="popup" // Required to handle step-up auth challenges via Universal Login popup
          >
            <Auth0ComponentProvider domain={domain}>
              <DomainsManagementPage />
            </Auth0ComponentProvider>
          </Auth0Provider>
        );
      }

      ```
    </Accordion>

    ## Props

    ### Display props

    Display props control how the component renders without affecting its behavior. Use these to hide sections or enable read-only mode.

    | Prop         | Type      | Description                                     |
    | :----------- | :-------- | :---------------------------------------------- |
    | `readOnly`   | `boolean` | Disable all domain operations. Default: `false` |
    | `hideHeader` | `boolean` | Hide the header section. Default: `false`       |

    ***

    ### Action props

    Action props handle user interactions and define what happens when users perform domain operations. Use lifecycle hooks (`onBefore`, `onAfter`) to integrate with your application's routing and analytics.

    | Prop                        | Type                                        | Description                                |
    | :-------------------------- | :------------------------------------------ | :----------------------------------------- |
    | `createAction`              | `ComponentAction<Domain>`                   | Create domain action.                      |
    | `verifyAction`              | `ComponentAction<Domain>`                   | Verify domain action.                      |
    | `deleteAction`              | `ComponentAction<Domain>`                   | Delete domain action.                      |
    | `associateToProviderAction` | `ComponentAction<Domain, IdentityProvider>` | Associate domain to provider.              |
    | `deleteFromProviderAction`  | `ComponentAction<Domain, IdentityProvider>` | Remove domain from provider.               |
    | `onOpenProvider`            | `(provider: IdentityProvider) => void`      | Navigate to provider from configure modal. |
    | `onCreateProvider`          | `() => void`                                | Navigate to create provider flow.          |

    **createAction**

    **Type:** `ComponentAction<Domain>`

    Controls the domain creation flow. Use `onAfter` to track when new domains are added.

    **Properties:**

    * `disabled`—Disable the "Add Domain" button
    * `onBefore(domain)`—Runs before the domain is created. Return `false` to prevent creation (for example, if the domain format is invalid).
    * `onAfter(domain)`—Runs after the domain is successfully created. Use this to show a notification or track the event.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      createAction={{
        onBefore: (domain) => {
          // Validate domain format
          if (!domain.domain.includes(".")) {
            alert("Please enter a valid domain");
            return false;
          }
          return true;
        },
        onAfter: (domain) => {
          analytics.track("Domain Created", { domain: domain.domain });
        },
      }}
    />
    ```

    ***

    **verifyAction**

    **Type:** `ComponentAction<Domain>`

    Controls the domain verification flow. Domain verification proves ownership via DNS TXT record.

    **Properties:**

    * `disabled`—Disable the verify button
    * `onBefore(domain)`—Runs before the verification attempt. Return `false` to prevent verification (for example, to confirm DNS is configured).
    * `onAfter(domain)`—Runs after the domain is successfully verified. Use this to show a success notification.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      verifyAction={{
        onBefore: (domain) => {
          return confirm(
            `Verify ${domain.domain}? Make sure your DNS record is configured.`,
          );
        },
        onAfter: (domain) => {
          toast.success(`${domain.domain} verified successfully!`);
        },
      }}
    />
    ```

    ***

    **deleteAction**

    **Type:** `ComponentAction<Domain>`

    Controls domain deletion. Recommended to use `onBefore` for confirmation since this is destructive.

    **Properties:**

    * `disabled`—Disable the delete button
    * `onBefore(domain)`—Runs before the deletion. Return `false` to prevent deletion (recommended for confirmation dialogs).
    * `onAfter(domain)`—Runs after the domain is successfully deleted. Use this to track the event or show a notification.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      deleteAction={{
        onBefore: (domain) => {
          return confirm(`Delete ${domain.domain}? This cannot be undone.`);
        },
        onAfter: (domain) => {
          analytics.track("Domain Deleted", { domain: domain.domain });
        },
      }}
    />
    ```

    ***

    **associateToProviderAction**

    **Type:** `ComponentAction<Domain, IdentityProvider>`

    Controls associating a verified domain with an SSO provider. Only verified domains can be associated.

    **Properties:**

    * `disabled`—Disable the associate action
    * `onBefore(domain, provider)`—Runs before the association. Return `false` to prevent the association.
    * `onAfter(domain, provider)`—Runs after the domain is successfully associated with the provider.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      associateToProviderAction={{
        onAfter: (domain, provider) => {
          console.log(`Associated ${domain.domain} with ${provider.name}`);
        },
      }}
    />
    ```

    ***

    **deleteFromProviderAction**

    **Type:** `ComponentAction<Domain, IdentityProvider>`

    Controls removing a domain's association with an SSO provider.

    **Properties:**

    * `disabled`—Disable the disassociate action
    * `onBefore(domain, provider)`—Runs before the removal. Return `false` to prevent the removal.
    * `onAfter(domain, provider)`—Runs after the domain is successfully removed from the provider.

    ***

    **onOpenProvider / onCreateProvider**

    **Type:** `(provider: IdentityProvider) => void` / `() => void`

    Navigation handlers for the domain configuration modal. When users configure a domain's provider associations:

    * `onOpenProvider`—Called when user clicks on an existing provider to view/edit it
    * `onCreateProvider`—Called when user clicks to create a new provider

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      onOpenProvider={(provider) => {
        navigate(`/providers/${provider.id}`);
      }}
      onCreateProvider={() => {
        navigate("/providers/create");
      }}
    />
    ```

    ***

    ### Customization props

    Customization props let you adapt the component to your brand, locale, and validation requirements without modifying source code.

    | Prop             | Type                               | Description                        |
    | :--------------- | :--------------------------------- | :--------------------------------- |
    | `schema`         | `DomainTableSchema`                | Domain URL validation rules.       |
    | `customMessages` | `Partial<DomainTableMainMessages>` | i18n text overrides.               |
    | `styling`        | `ComponentStyling`                 | CSS variables and class overrides. |

    **schema**

    Set custom validation rules for domain URL input.

    <Accordion title="Available Schema Fields">
      **create.domainUrl**—Domain URL validation—`regex`—Custom regex pattern

      * `errorMessage`—Custom error message
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      schema={{
        create: {
          domain: {
            regex: /^[a-z0-9.-]+\.[a-z]{2,}$/,
            errorMessage: "Enter a valid domain (example.com)",
          },
        },
      }}
    />
    ```

    ***

    **customMessages**

    Customize all text and translations. All fields are optional and use defaults if not provided.

    <Accordion title="Available Messages">
      **header**—Component header

      * `title`, `description`, `create_button_text`

      **table**—Table display

      * `empty_message`
      * `columns.domain`, `columns.status`
      * `actions.configure_button_text`, `actions.verify_button_text`, `actions.delete_button_text`

      **create.modal**—Create domain modal

      * `title`
      * `field.label`, `field.placeholder`, `field.error`
      * `actions.cancel_button_text`, `actions.create_button_text`

      **verify.modal**—Verify domain modal

      * `title`
      * `txt_record_name.label`, `txt_record_content.label`, `verification_status.label`
      * `actions.verify_button_text`, `actions.done_button_text`

      **delete.modal**—Delete confirmation

      * `title`
      * `description.pending`, `description.verified`
      * `actions.cancel_button_text`, `actions.create_button_text`

      **configure.modal**—Provider configuration

      * `title`, `description`
      * `table.empty_message`, `table.columns.name`
      * `actions.close_button_text`

      **notifications**—API responses

      * `domain_create_success`, `domain_create_error`
      * `domain_verify_success`, `domain_delete_success`
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      customMessages={{
        header: {
          title: "Manage Domains",
          description: "Configure and verify organization domains",
          create_button_text: "Add Domain",
        },
        table: {
          empty_message: "No domains yet. Add one to begin.",
        },
        notifications: {
          domain_create_success: "Domain added successfully!",
          domain_verify_success: "Domain verified!",
          domain_delete_success: "Domain removed.",
        },
      }}
    />
    ```

    ***

    **styling**

    Customize appearance with CSS variables and class overrides. Supports theme-aware styling.

    <Accordion title="Available Styling Options">
      **Variables**—CSS custom properties

      * `common`—Applied to all themes
      * `light`—Light theme only
      * `dark`—Dark theme only

      **Classes**—Component class overrides

      * `DomainTable-header`
      * `DomainTable-table`
      * `DomainTable-createModal`
      * `DomainTable-configureModal`
      * `DomainTable-deleteModal`
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      styling={{
        variables: {
          common: { "--font-size-title": "1rem" },
          light: { "--color-primary": "#4f46e5" },
        },
        classes: {
          "DomainTable-header": "mb-6",
          "DomainTable-table": "rounded-lg shadow-sm",
        },
      }}
    />
    ```

    ***

    ## Advanced customization

    The `DomainTable` component is composed of smaller subcomponents and hooks. You can import them individually to build custom domain workflows if you use shadcn.

    ### Available subcomponents

    For advanced use cases, you can import individual subcomponents to build custom domain management interfaces. This is useful when you need to embed specific modals in different contexts or customize the table layout beyond what props allow.

    | Component                       | Description                        |
    | :------------------------------ | :--------------------------------- |
    | `DomainCreateModal`             | Modal for creating a domain        |
    | `DomainVerifyModal`             | Modal for verification flow        |
    | `DomainDeleteModal`             | Confirmation modal for deletion    |
    | `DomainConfigureProvidersModal` | Manage provider associations       |
    | `DomainTableActionsColumn`      | Action buttons for each domain row |

    ### Available hooks

    These hooks provide the underlying logic without any UI. Use them to build completely custom interfaces while leveraging the Auth0 API integration.

    | Hook                  | Description                                                 |
    | :-------------------- | :---------------------------------------------------------- |
    | `useDomainTable`      | Data + API layer (fetch, create, verify, delete, associate) |
    | `useDomainTableLogic` | UI interaction state + handlers (modals, notifications)     |
  </Tab>

  <Tab title="Next.js">
    ## Setup requirements

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      **Auth0 Configuration Required**—Ensure your tenant is configured with the
      My Organization API. [View setup guide
      →](/docs/get-started/universal-components/web/components/build-delegated-admin#configure-auth0-dashboard)
    </Callout>

    ## Install component

    <CodeGroup>
      ```bash npm  wrap lines theme={null}
      npm install @auth0/universal-components-react
      ```

      ```bash pnpm wrap lines theme={null}
      pnpm add @auth0/universal-components-react
      ```
    </CodeGroup>

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      Running the pnpm or npm commands installs the @auth0/universal-components-core
      dependency for shared utilities and Auth0 integration.
    </Callout>

    ## Get started

    ```tsx page.tsx wrap lines theme={null}
    import { DomainTable } from "@auth0/universal-components-react";
    import { useRouter } from "next/navigation";

    export function DomainsPage() {
      const router = useRouter();

      return (
        <DomainTable
          onOpenProvider={(provider) => {
            router.push(`/providers/${provider.id}`);
          }}
          onCreateProvider={() => {
            router.push("/providers/create");
          }}
        />
      );
    }
    ```

    <Accordion title="Full integration example">
      ```tsx wrap lines theme={null}
      import React from "react";
      import { DomainTable } from "@auth0/universal-components-react";
      import { useRouter } from "next/navigation";

      function DomainsManagementPage() {
        const router = useRouter();

        return (
          <div className="max-w-6xl mx-auto p-6">
            <DomainTable
              schema={{
                create: {
                  domain: {
                    regex: /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i,
                    errorMessage: "Please enter a valid domain (e.g., example.com)",
                  },
                },
              }}
              createAction={{
                onBefore: (domain) => {
                  if (!domain.domain.includes(".")) {
                    alert("Please enter a valid domain with a TLD");
                    return false;
                  }
                  return true;
                },
                onAfter: (domain) => console.log("Domain created:", domain),
              }}
              verifyAction={{
                onAfter: (domain) => {
                  console.log("Domain verified:", domain.domain);
                },
              }}
              deleteAction={{
                onBefore: (domain) => {
                  return confirm(`Delete ${domain.domain}?`);
                },
              }}
              onOpenProvider={(provider) => {
                router.push(`/providers/${provider.id}`);
              }}
              onCreateProvider={() => {
                router.push("/providers/create");
              }}
              customMessages={{
                header: {
                  title: "Domain Management",
                  description: "Add and verify domains for your organization",
                  create_button_text: "Add New Domain",
                },
              }}
              styling={{
                variables: {
                  common: { "--font-size-label": "12px" },
                  light: { "--color-primary": "#0066cc" },
                },
                classes: {
                  "DomainTable-header": "shadow-lg rounded-xl",
                },
              }}
            />
          </div>
        );
      }

      export default DomainsManagementPage;
      ```
    </Accordion>

    ## Props

    ### Display props

    Display props control how the component renders without affecting its behavior. Use these to hide sections or enable read-only mode.

    <table class="table">
      <thead>
        <tr>
          <th>Prop</th>
          <th>Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>readOnly</code>
          </td>

          <td>
            <code>boolean</code>
          </td>

          <td>
            Disable all domain operations. Default: <code>false</code>
          </td>
        </tr>

        <tr>
          <td>
            <code>hideHeader</code>
          </td>

          <td>
            <code>boolean</code>
          </td>

          <td>
            Hide the header section. Default: <code>false</code>
          </td>
        </tr>
      </tbody>
    </table>

    ***

    ### Action props

    Action props handle user interactions and define what happens when users perform domain operations. Use lifecycle hooks (`onBefore`, `onAfter`) to integrate with your application's routing and analytics.

    <table class="table">
      <thead>
        <tr>
          <th>Prop</th>
          <th>Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>createAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain></code>
          </td>

          <td>
            Create domain action.
          </td>
        </tr>

        <tr>
          <td>
            <code>verifyAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain></code>
          </td>

          <td>
            Verify domain action.
          </td>
        </tr>

        <tr>
          <td>
            <code>deleteAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain></code>
          </td>

          <td>
            Delete domain action.
          </td>
        </tr>

        <tr>
          <td>
            <code>associateToProviderAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain, IdentityProvider></code>
          </td>

          <td>
            Associate domain to provider.
          </td>
        </tr>

        <tr>
          <td>
            <code>deleteFromProviderAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain, IdentityProvider></code>
          </td>

          <td>
            Remove domain from provider.
          </td>
        </tr>

        <tr>
          <td>
            <code>onOpenProvider</code>
          </td>

          <td>
            <code>(provider: IdentityProvider) => void</code>
          </td>

          <td>
            Navigate to provider from configure modal.
          </td>
        </tr>

        <tr>
          <td>
            <code>onCreateProvider</code>
          </td>

          <td>
            <code>() => void</code>
          </td>

          <td>
            Navigate to create provider flow.
          </td>
        </tr>
      </tbody>
    </table>

    **createAction**

    **Type:** `ComponentAction<Domain>`

    Controls the domain creation flow. Use `onAfter` to track when new domains are added.

    **Properties:**

    * `disabled`—Disable the "Add Domain" button
    * `onBefore(domain)`—Runs before the domain is created. Return `false` to prevent creation (for example, if the domain format is invalid).
    * `onAfter(domain)`—Runs after the domain is successfully created. Use this to show a notification or track the event.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      createAction={{
        onBefore: (domain) => {
          // Validate domain format
          if (!domain.domain.includes(".")) {
            alert("Please enter a valid domain");
            return false;
          }
          return true;
        },
        onAfter: (domain) => {
          analytics.track("Domain Created", { domain: domain.domain });
        },
      }}
    />
    ```

    ***

    **verifyAction**

    **Type:** `ComponentAction<Domain>`

    Controls the domain verification flow. Domain verification proves ownership via DNS TXT record.

    **Properties:**

    * `disabled`—Disable the verify button
    * `onBefore(domain)`—Runs before the verification attempt. Return `false` to prevent verification (for example, to confirm DNS is configured).
    * `onAfter(domain)`—Runs after the domain is successfully verified. Use this to show a success notification.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      verifyAction={{
        onBefore: (domain) => {
          return confirm(
            `Verify ${domain.domain}? Make sure your DNS record is configured.`,
          );
        },
        onAfter: (domain) => {
          toast.success(`${domain.domain} verified successfully!`);
        },
      }}
    />
    ```

    ***

    **deleteAction**

    **Type:** `ComponentAction<Domain>`

    Controls domain deletion. Recommended to use `onBefore` for confirmation since this is destructive.

    **Properties:**

    * `disabled`—Disable the delete button
    * `onBefore(domain)`—Runs before the deletion. Return `false` to prevent deletion (recommended for confirmation dialogs).
    * `onAfter(domain)`—Runs after the domain is successfully deleted. Use this to track the event or show a notification.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      deleteAction={{
        onBefore: (domain) => {
          return confirm(`Delete ${domain.domain}? This cannot be undone.`);
        },
        onAfter: (domain) => {
          analytics.track("Domain Deleted", { domain: domain.domain });
        },
      }}
    />
    ```

    ***

    **associateToProviderAction**

    **Type:** `ComponentAction<Domain, IdentityProvider>`

    Controls associating a verified domain with an SSO provider. Only verified domains can be associated.

    **Properties:**

    * `disabled`—Disable the associate action
    * `onBefore(domain, provider)`—Runs before the association. Return `false` to prevent the association.
    * `onAfter(domain, provider)`—Runs after the domain is successfully associated with the provider.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      associateToProviderAction={{
        onAfter: (domain, provider) => {
          console.log(`Associated ${domain.domain} with ${provider.name}`);
        },
      }}
    />
    ```

    ***

    **deleteFromProviderAction**

    **Type:** `ComponentAction<Domain, IdentityProvider>`

    Controls removing a domain's association with an SSO provider.

    **Properties:**

    * `disabled`—Disable the disassociate action
    * `onBefore(domain, provider)`—Runs before the removal. Return `false` to prevent the removal.
    * `onAfter(domain, provider)`—Runs after the domain is successfully removed from the provider.

    ***

    **onOpenProvider / onCreateProvider**

    **Type:** `(provider: IdentityProvider) => void` / `() => void`

    Navigation handlers for the domain configuration modal. When users configure a domain's provider associations:

    * `onOpenProvider`—Called when user clicks on an existing provider to view/edit it
    * `onCreateProvider`—Called when user clicks to create a new provider

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      onOpenProvider={(provider) => {
        router.push(`/providers/${provider.id}`);
      }}
      onCreateProvider={() => {
        router.push("/providers/create");
      }}
    />
    ```

    ***

    ### Customization props

    Customization props let you adapt the component to your brand, locale, and validation requirements without modifying source code.

    <table class="table">
      <thead>
        <tr>
          <th>Prop</th>
          <th>Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>schema</code>
          </td>

          <td>
            <code>DomainTableSchema</code>
          </td>

          <td>
            Domain URL validation rules.
          </td>
        </tr>

        <tr>
          <td>
            <code>customMessages</code>
          </td>

          <td>
            <code>Partial\<DomainTableMainMessages></code>
          </td>

          <td>
            i18n text overrides.
          </td>
        </tr>

        <tr>
          <td>
            <code>styling</code>
          </td>

          <td>
            <code>ComponentStyling</code>
          </td>

          <td>
            CSS variables and class overrides.
          </td>
        </tr>
      </tbody>
    </table>

    **schema**

    Set custom validation rules for domain URL input.

    <Accordion title="Available Schema Fields">
      **create.domain**—Domain URL validation—`regex`—Custom regex pattern -
      `errorMessage`—Custom error message
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      schema={{
        create: {
          domain: {
            regex: /^[a-z0-9.-]+\.[a-z]{2,}$/,
            errorMessage: "Enter a valid domain (example.com)",
          },
        },
      }}
    />
    ```

    ***

    **customMessages**

    Customize all text and translations. All fields are optional and use defaults if not provided.

    <Accordion title="Available Messages">
      **header**—Component header

      * `title`, `description`, `create_button_text`

      **table**—Table display

      * `empty_message`
      * `columns.domain`, `columns.status`
      * `actions.configure_button_text`, `actions.verify_button_text`, `actions.delete_button_text`

      **create.modal**—Create domain modal

      * `title`
      * `field.label`, `field.placeholder`, `field.error`
      * `actions.cancel_button_text`, `actions.create_button_text`

      **verify.modal**—Verify domain modal

      * `title`
      * `txt_record_name.label`, `txt_record_content.label`, `verification_status.label`
      * `actions.verify_button_text`, `actions.done_button_text`

      **delete.modal**—Delete confirmation

      * `title`
      * `description.pending`, `description.verified`
      * `actions.cancel_button_text`, `actions.create_button_text`

      **configure.modal**—Provider configuration

      * `title`, `description`
      * `table.empty_message`, `table.columns.name`
      * `actions.close_button_text`

      **notifications**—API responses

      * `domain_create_success`, `domain_create_error`
      * `domain_verify_success`, `domain_delete_success`
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      customMessages={{
        header: {
          title: "Manage Domains",
          description: "Configure and verify organization domains",
          create_button_text: "Add Domain",
        },
        table: {
          empty_message: "No domains yet. Add one to begin.",
        },
        notifications: {
          domain_create_success: "Domain added successfully!",
          domain_verify_success: "Domain verified!",
          domain_delete_success: "Domain removed.",
        },
      }}
    />
    ```

    ***

    **styling**

    Customize appearance with CSS variables and class overrides. Supports theme-aware styling.

    <Accordion title="Available Styling Options">
      **Variables**—CSS custom properties

      * `common`—Applied to all themes
      * `light`—Light theme only
      * `dark`—Dark theme only

      **Classes**—Component class overrides

      * `DomainTable-header`
      * `DomainTable-table`
      * `DomainTable-createModal`
      * `DomainTable-configureModal`
      * `DomainTable-deleteModal`
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      styling={{
        variables: {
          common: { "--font-size-title": "1rem" },
          light: { "--color-primary": "#4f46e5" },
        },
        classes: {
          "DomainTable-header": "mb-6",
          "DomainTable-table": "rounded-lg shadow-sm",
        },
      }}
    />
    ```

    ***

    ## Advanced customization

    The `DomainTable` component is composed of smaller subcomponents and hooks. You can import them individually to build custom domain workflows.

    ### Available subcomponents

    For advanced use cases, you can import individual subcomponents to build custom domain management interfaces. This is useful when you need to embed specific modals in different contexts or customize the table layout beyond what props allow.

    <table class="table">
      <thead>
        <tr>
          <th>Component</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>DomainCreateModal</code>
          </td>

          <td>Modal for creating a domain</td>
        </tr>

        <tr>
          <td>
            <code>DomainVerifyModal</code>
          </td>

          <td>Modal for verification flow</td>
        </tr>

        <tr>
          <td>
            <code>DomainDeleteModal</code>
          </td>

          <td>Confirmation modal for deletion</td>
        </tr>

        <tr>
          <td>
            <code>DomainConfigureProvidersModal</code>
          </td>

          <td>Manage provider associations</td>
        </tr>

        <tr>
          <td>
            <code>DomainTableActionsColumn</code>
          </td>

          <td>Action buttons for each domain row</td>
        </tr>
      </tbody>
    </table>

    ### Available hooks

    These hooks provide the underlying logic without any UI. Use them to build completely custom interfaces while leveraging the Auth0 API integration.

    <table class="table">
      <thead>
        <tr>
          <th>Hook</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>useDomainTable</code>
          </td>

          <td>Data + API layer (fetch, create, verify, delete, associate)</td>
        </tr>

        <tr>
          <td>
            <code>useDomainTableLogic</code>
          </td>

          <td>UI interaction state + handlers (modals, notifications)</td>
        </tr>
      </tbody>
    </table>
  </Tab>

  <Tab title="shadcn">
    ## Setup requirements

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      **Auth0 Configuration Required**—Ensure your tenant is configured with the
      My Organization API. [View setup guide
      →](/docs/get-started/universal-components/web/components/build-delegated-admin#configure-auth0-dashboard)
    </Callout>

    ## Install the component

    ```bash wrap lines theme={null}
    npx shadcn@latest add https://auth0-universal-components.vercel.app/r/my-organization/domain-table.json
    ```

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      Running the shadcn command also installs the @auth0/universal-components-core
      dependency for shared utilities and Auth0 integration.
    </Callout>

    ## Get started

    ```tsx wrap lines theme={null}
    import { DomainTable } from "@/components/auth0/my-organization/domain-table";

    export function DomainsPage() {
      return <DomainTable />;
    }
    ```

    <Accordion title="Full integration example">
      ```tsx wrap lines theme={null}
      import React from "react";
      import { DomainTable } from "@/components/auth0/my-organization/domain-table";
      import { Auth0Provider } from "@auth0/auth0-react";
      import { Auth0ComponentProvider } from "@auth0/universal-components-react/spa";
      import { useNavigate } from "react-router-dom";

      function DomainsManagementPage() {
        const navigate = useNavigate();

        return (
          <div className="max-w-6xl mx-auto p-6">
            <DomainTable
              schema={{
                create: {
                  domain: {
                    regex: /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i,
                    errorMessage: "Please enter a valid domain (e.g., example.com)",
                  },
                },
              }}
              createAction={{
                onBefore: (domain) => {
                  if (!domain.domain.includes(".")) {
                    alert("Please enter a valid domain with a TLD");
                    return false;
                  }
                  return true;
                },
                onAfter: (domain) => console.log("Domain created:", domain),
              }}
              verifyAction={{
                onAfter: (domain) => {
                  console.log("Domain verified:", domain.domain);
                },
              }}
              deleteAction={{
                onBefore: (domain) => {
                  return confirm(`Delete ${domain.domain}?`);
                },
              }}
              onOpenProvider={(provider) => {
                navigate(`/providers/${provider.id}`);
              }}
              onCreateProvider={() => {
                navigate("/providers/create");
              }}
              customMessages={{
                header: {
                  title: "Domain Management",
                  description: "Add and verify domains for your organization",
                  create_button_text: "Add New Domain",
                },
              }}
              styling={{
                variables: {
                  common: { "--font-size-label": "12px" },
                  light: { "--color-primary": "#0066cc" },
                },
                classes: {
                  "DomainTable-header": "shadow-lg rounded-xl",
                },
              }}
            />
          </div>
        );
      }

      export default function App() {
        const domain = "your-domain.auth0.com";

        return (
          <Auth0Provider
            domain={domain}
            clientId="your-client-id"
            authorizationParams={{
              redirect_uri: window.location.origin,
            }}
            interactiveErrorHandler="popup" // Required to handle step-up auth challenges via Universal Login popup
          >
            <Auth0ComponentProvider domain={domain}>
              <DomainsManagementPage />
            </Auth0ComponentProvider>
          </Auth0Provider>
        );
      }

      ```
    </Accordion>

    ## Props

    ### Display props

    Display props control how the component renders without affecting its behavior. Use these to hide sections or enable read-only mode.

    <table class="table">
      <thead>
        <tr>
          <th>Prop</th>
          <th>Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>readOnly</code>
          </td>

          <td>
            <code>boolean</code>
          </td>

          <td>
            Disable all domain operations. Default: <code>false</code>
          </td>
        </tr>

        <tr>
          <td>
            <code>hideHeader</code>
          </td>

          <td>
            <code>boolean</code>
          </td>

          <td>
            Hide the header section. Default: <code>false</code>
          </td>
        </tr>
      </tbody>
    </table>

    ***

    ### Action props

    Action props handle user interactions and define what happens when users perform domain operations. Use lifecycle hooks (`onBefore`, `onAfter`) to integrate with your application's routing and analytics.

    <table class="table">
      <thead>
        <tr>
          <th>Prop</th>
          <th>Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>createAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain></code>
          </td>

          <td>
            Create domain action.
          </td>
        </tr>

        <tr>
          <td>
            <code>verifyAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain></code>
          </td>

          <td>
            Verify domain action.
          </td>
        </tr>

        <tr>
          <td>
            <code>deleteAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain></code>
          </td>

          <td>
            Delete domain action.
          </td>
        </tr>

        <tr>
          <td>
            <code>associateToProviderAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain, IdentityProvider></code>
          </td>

          <td>
            Associate domain to provider.
          </td>
        </tr>

        <tr>
          <td>
            <code>deleteFromProviderAction</code>
          </td>

          <td>
            <code>ComponentAction\<Domain, IdentityProvider></code>
          </td>

          <td>
            Remove domain from provider.
          </td>
        </tr>

        <tr>
          <td>
            <code>onOpenProvider</code>
          </td>

          <td>
            <code>(provider: IdentityProvider) => void</code>
          </td>

          <td>
            Navigate to provider from configure modal.
          </td>
        </tr>

        <tr>
          <td>
            <code>onCreateProvider</code>
          </td>

          <td>
            <code>() => void</code>
          </td>

          <td>
            Navigate to create provider flow.
          </td>
        </tr>
      </tbody>
    </table>

    **createAction**

    **Type:** `ComponentAction<Domain>`

    Controls the domain creation flow. Use `onAfter` to track when new domains are added.

    **Properties:**

    * `disabled`—Disable the "Add Domain" button
    * `onBefore(domain)`—Runs before the domain is created. Return `false` to prevent creation (for example, if the domain format is invalid).
    * `onAfter(domain)`—Runs after the domain is successfully created. Use this to show a notification or track the event.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      createAction={{
        onBefore: (domain) => {
          // Validate domain format
          if (!domain.domain.includes(".")) {
            alert("Please enter a valid domain");
            return false;
          }
          return true;
        },
        onAfter: (domain) => {
          analytics.track("Domain Created", { domain: domain.domain });
        },
      }}
    />
    ```

    ***

    **verifyAction**

    **Type:** `ComponentAction<Domain>`

    Controls the domain verification flow. Domain verification proves ownership via DNS TXT record.

    **Properties:**

    * `disabled`—Disable the verify button
    * `onBefore(domain)`—Runs before the verification attempt. Return `false` to prevent verification (for example, to confirm DNS is configured).
    * `onAfter(domain)`—Runs after the domain is successfully verified. Use this to show a success notification.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      verifyAction={{
        onBefore: (domain) => {
          return confirm(
            `Verify ${domain.domain}? Make sure your DNS record is configured.`,
          );
        },
        onAfter: (domain) => {
          toast.success(`${domain.domain} verified successfully!`);
        },
      }}
    />
    ```

    ***

    **deleteAction**

    **Type:** `ComponentAction<Domain>`

    Controls domain deletion. Recommended to use `onBefore` for confirmation since this is destructive.

    **Properties:**

    * `disabled`—Disable the delete button
    * `onBefore(domain)`—Runs before the deletion. Return `false` to prevent deletion (recommended for confirmation dialogs).
    * `onAfter(domain)`—Runs after the domain is successfully deleted. Use this to track the event or show a notification.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      deleteAction={{
        onBefore: (domain) => {
          return confirm(`Delete ${domain.domain}? This cannot be undone.`);
        },
        onAfter: (domain) => {
          analytics.track("Domain Deleted", { domain: domain.domain });
        },
      }}
    />
    ```

    ***

    **associateToProviderAction**

    **Type:** `ComponentAction<Domain, IdentityProvider>`

    Controls associating a verified domain with an SSO provider. Only verified domains can be associated.

    **Properties:**

    * `disabled`—Disable the associate action
    * `onBefore(domain, provider)`—Runs before the association. Return `false` to prevent the association.
    * `onAfter(domain, provider)`—Runs after the domain is successfully associated with the provider.

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      associateToProviderAction={{
        onAfter: (domain, provider) => {
          console.log(`Associated ${domain.domain} with ${provider.name}`);
        },
      }}
    />
    ```

    ***

    **deleteFromProviderAction**

    **Type:** `ComponentAction<Domain, IdentityProvider>`

    Controls removing a domain's association with an SSO provider.

    **Properties:**

    * `disabled`—Disable the disassociate action
    * `onBefore(domain, provider)`—Runs before the removal. Return `false` to prevent the removal.
    * `onAfter(domain, provider)`—Runs after the domain is successfully removed from the provider.

    ***

    **onOpenProvider / onCreateProvider**

    **Type:** `(provider: IdentityProvider) => void` / `() => void`

    Navigation handlers for the domain configuration modal. When users configure a domain's provider associations:

    * `onOpenProvider`—Called when user clicks on an existing provider to view/edit it
    * `onCreateProvider`—Called when user clicks to create a new provider

    **Example:**

    ```tsx wrap lines theme={null}
    <DomainTable
      onOpenProvider={(provider) => {
        navigate(`/providers/${provider.id}`);
      }}
      onCreateProvider={() => {
        navigate("/providers/create");
      }}
    />
    ```

    ***

    ### Customization props

    Customization props let you adapt the component to your brand, locale, and validation requirements without modifying source code.

    <table class="table">
      <thead>
        <tr>
          <th>Prop</th>
          <th>Type</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>schema</code>
          </td>

          <td>
            <code>DomainTableSchema</code>
          </td>

          <td>
            Domain URL validation rules.
          </td>
        </tr>

        <tr>
          <td>
            <code>customMessages</code>
          </td>

          <td>
            <code>Partial\<DomainTableMainMessages></code>
          </td>

          <td>
            i18n text overrides.
          </td>
        </tr>

        <tr>
          <td>
            <code>styling</code>
          </td>

          <td>
            <code>ComponentStyling</code>
          </td>

          <td>
            CSS variables and class overrides.
          </td>
        </tr>
      </tbody>
    </table>

    **schema**

    Set custom validation rules for domain URL input.

    <Accordion title="Available Schema Fields">
      **create.domainUrl**—Domain URL validation—`regex`—Custom regex pattern

      * `errorMessage`—Custom error message
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      schema={{
        create: {
          domain: {
            regex: /^[a-z0-9.-]+\.[a-z]{2,}$/,
            errorMessage: "Enter a valid domain (example.com)",
          },
        },
      }}
    />
    ```

    ***

    **customMessages**

    Customize all text and translations. All fields are optional and use defaults if not provided.

    <Accordion title="Available Messages">
      **header**—Component header

      * `title`, `description`, `create_button_text`

      **table**—Table display

      * `empty_message`
      * `columns.domain`, `columns.status`
      * `actions.configure_button_text`, `actions.verify_button_text`, `actions.delete_button_text`

      **create.modal**—Create domain modal

      * `title`
      * `field.label`, `field.placeholder`, `field.error`
      * `actions.cancel_button_text`, `actions.create_button_text`

      **verify.modal**—Verify domain modal

      * `title`
      * `txt_record_name.label`, `txt_record_content.label`, `verification_status.label`
      * `actions.verify_button_text`, `actions.done_button_text`

      **delete.modal**—Delete confirmation

      * `title`
      * `description.pending`, `description.verified`
      * `actions.cancel_button_text`, `actions.create_button_text`

      **configure.modal**—Provider configuration

      * `title`, `description`
      * `table.empty_message`, `table.columns.name`
      * `actions.close_button_text`

      **notifications**—API responses

      * `domain_create_success`, `domain_create_error`
      * `domain_verify_success`, `domain_delete_success`
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      customMessages={{
        header: {
          title: "Manage Domains",
          description: "Configure and verify organization domains",
          create_button_text: "Add Domain",
        },
        table: {
          empty_message: "No domains yet. Add one to begin.",
        },
        notifications: {
          domain_create_success: "Domain added successfully!",
          domain_verify_success: "Domain verified!",
          domain_delete_success: "Domain removed.",
        },
      }}
    />
    ```

    ***

    **styling**

    Customize appearance with CSS variables and class overrides. Supports theme-aware styling.

    <Accordion title="Available Styling Options">
      **Variables**—CSS custom properties

      * `common`—Applied to all themes
      * `light`—Light theme only
      * `dark`—Dark theme only

      **Classes**—Component class overrides

      * `DomainTable-header`
      * `DomainTable-table`
      * `DomainTable-createModal`
      * `DomainTable-configureModal`
      * `DomainTable-deleteModal`
    </Accordion>

    ```tsx wrap lines theme={null}
    <DomainTable
      styling={{
        variables: {
          common: { "--font-size-title": "1rem" },
          light: { "--color-primary": "#4f46e5" },
        },
        classes: {
          "DomainTable-header": "mb-6",
          "DomainTable-table": "rounded-lg shadow-sm",
        },
      }}
    />
    ```

    ***

    ## Advanced customization

    The `DomainTable` component is composed of smaller subcomponents and hooks. You can import them individually to build custom domain workflows if you use shadcn.

    ### Available subcomponents

    For advanced use cases, you can import individual subcomponents to build custom domain management interfaces. This is useful when you need to embed specific modals in different contexts or customize the table layout beyond what props allow.

    <table class="table">
      <thead>
        <tr>
          <th>Component</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>DomainCreateModal</code>
          </td>

          <td>Modal for creating a domain</td>
        </tr>

        <tr>
          <td>
            <code>DomainVerifyModal</code>
          </td>

          <td>Modal for verification flow</td>
        </tr>

        <tr>
          <td>
            <code>DomainDeleteModal</code>
          </td>

          <td>Confirmation modal for deletion</td>
        </tr>

        <tr>
          <td>
            <code>DomainConfigureProvidersModal</code>
          </td>

          <td>Manage provider associations</td>
        </tr>

        <tr>
          <td>
            <code>DomainTableActionsColumn</code>
          </td>

          <td>Action buttons for each domain row</td>
        </tr>
      </tbody>
    </table>

    ### Available hooks

    These hooks provide the underlying logic without any UI. Use them to build completely custom interfaces while leveraging the Auth0 API integration.

    <table class="table">
      <thead>
        <tr>
          <th>Hook</th>
          <th>Description</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td>
            <code>useDomainTable</code>
          </td>

          <td>Data + API layer (fetch, create, verify, delete, associate)</td>
        </tr>

        <tr>
          <td>
            <code>useDomainTableLogic</code>
          </td>

          <td>UI interaction state + handlers (modals, notifications)</td>
        </tr>
      </tbody>
    </table>
  </Tab>
</Tabs>
