Skip to main content
Since Shoelace 2.0 Code stable Pattern stable Figma ready

Alert

<sl-alert> | SlAlert

Alerts are used to display important messages inline or as toast notifications.

Examples

Basic Alert

This is the alert header
This is the alert message. Keep it simple!
<sl-alert open>
  <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon>
  <div slot="header">This is the alert header</div>
  This is the alert message. Keep it simple!
</sl-alert>
sl-alert open="true"
  sl-icon slot="icon" library="fa" name="fas-circle-info"
  div slot="header" This is the alert header
  | This is the alert message. Keep it simple!
import { SlAlert, SlIcon } from '@teamshares/shoelace/dist/react';

const App = () => (
  <SlAlert open>
    <SlIcon slot="icon" library="fa" name="fas-circle-info" />
    <div slot="header">This is super informative</div>
    This is a standard standard informational alert.
  </SlAlert>
);

Variants

Set the variant attribute to change the alert’s variant.

We’ve simplified your login experience
You can now log in to both apps with one set of credentials.

Request approved
This request was approved on April 25, 2024.

This view is currently hidden from shareholders
Go to Company settings to edit the visibility of this page.

Your payment is past due
To avoid late fees, pay your minimum amount due today.
<sl-alert variant="primary" open>
  <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon>
  <div slot="header">We’ve simplified your login experience</div>
  You can now log in to both apps with one set of credentials.
</sl-alert>

<br />

<sl-alert variant="success" open>
  <sl-icon slot="icon" library="fa" name="fas-circle-check"></sl-icon>
  <div slot="header">Request approved</div>
  This request was approved on April 25, 2024.
</sl-alert>

<br />

<sl-alert variant="warning" open>
  <sl-icon slot="icon" library="fa" name="fas-triangle-exclamation"></sl-icon>
  <div slot="header">This view is currently hidden from shareholders</div>
  Go to <a class="ts-text-link" href="#">Company settings</a> to edit the visibility of this page.
</sl-alert>

<br />

<sl-alert variant="danger" open>
  <sl-icon slot="icon" library="fa" name="fas-circle-exclamation"></sl-icon>
  <div slot="header">Your payment is past due</div>
  To avoid late fees, pay your minimum amount due today.
</sl-alert>
sl-alert variant="primary" open="true"
  sl-icon slot="icon" library="fa" name="fas-circle-info"
  div slot="header" We’ve simplified your login experience!
  | You can now log in to both apps with one set of credentials.
br
sl-alert variant="success" open="true"
  sl-icon slot="icon" library="fa" name="fas-circle-check"
  div slot="header" Request approved
  |  This request was approved on April 25, 2024.
br
sl-alert variant="warning" open="true"
  sl-icon slot="icon" library="fa" name="fas-triangle-exclamation"
  div slot="header" This view is currently hidden from shareholders
  | Go to
  a class="ts-text-link" href="#" Company settings
  | to edit the visibility of this page.
br
sl-alert variant="danger" open="true"
  sl-icon slot="icon" library="fa" name="fas-circle-exclamation"
  div slot="header" Your payment is past due
  | To avoid late fees, pay your minimum amount due today.
import { SlAlert, SlIcon } from '@teamshares/shoelace/dist/react';

const App = () => (
  <>
    <SlAlert variant="primary" open>
      <SlIcon slot="icon" library="fa" name="fas-circle-info" />
      <div slot="header">This is super informative</div>
      You can tell by how pretty the alert is.
    </SlAlert>

    <br />

    <SlAlert variant="success" open>
      <SlIcon slot="icon" library="fa" name="fas-circle-check" />
      <div slot="header">Your changes have been saved</div>
      You can safely exit the app now.
    </SlAlert>

    <br />

    <SlAlert variant="warning" open>
      <SlIcon slot="icon" library="fa" name="fas-triangle-exclamation" />
      <div slot="header">Your session has ended</div>
      Please login again to continue.
    </SlAlert>

    <br />

    <SlAlert variant="danger" open>
      <SlIcon slot="icon" library="fa" name="fas-circle-exclamation" />
      <div slot="header">Your account has been deleted</div>
      We are very sorry to see you go!
    </SlAlert>
  </>
);

Closable

Add the closable attribute to show a close button that will hide the alert.

You can close this alert any time!
<sl-alert variant="primary" open closable class="alert-closable">
  <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon>
  You can close this alert any time!
</sl-alert>

<script>
  const alert = document.querySelector('.alert-closable');
  alert.addEventListener('sl-after-hide', () => {
    setTimeout(() => (alert.open = true), 2000);
  });
</script>
sl-alert.alert-closable variant="primary" open="true" closable="true"
  sl-icon slot="icon" library="fa" name="fas-circle-info"
  | You can close this alert any time!

javascript:
  const alert = document.querySelector(.alert-closable);
  alert.addEventListener(sl-after-hide, () => {
    setTimeout(() => (alert.open = true), 2000);
  });
import { useState } from 'react';
import { SlAlert, SlIcon } from '@teamshares/shoelace/dist/react';

const App = () => {
  const [open, setOpen] = useState(true);

  function handleHide() {
    setOpen(false);
    setTimeout(() => setOpen(true), 2000);
  }

  return (
    <SlAlert open={open} closable onSlAfterHide={handleHide}>
      <SlIcon slot="icon" library="fa" name="fas-circle-info" />
      You can close this alert any time!
    </SlAlert>
  );
};

Duration

Set the duration attribute to automatically hide an alert after a period of time. This is useful for alerts that don’t require acknowledgement.

Show Alert This alert will automatically hide itself after three seconds, unless you interact with it.
<div class="alert-duration">
  <sl-button variant="primary">Show Alert</sl-button>

  <sl-alert variant="primary" duration="3000" closable>
    <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon>
    This alert will automatically hide itself after three seconds, unless you interact with it.
  </sl-alert>
</div>

<script>
  const container = document.querySelector('.alert-duration');
  const button = container.querySelector('sl-button');
  const alert = container.querySelector('sl-alert');

  button.addEventListener('click', () => alert.show());
</script>

<style>
  .alert-duration sl-alert {
    margin-top: var(--sl-spacing-medium);
  }
</style>
div.alert-duration
  sl-button variant="primary" Show Alert
  sl-alert variant="primary" duration="3000" closable="true"
    sl-icon slot="icon" library="fa" name="fas-circle-info"
    | This alert will automatically hide itself after three seconds, unless you interact with it.

javascript:
  const container = document.querySelector(.alert-duration);
  const button = container.querySelector(sl-button);
  const alert = container.querySelector(sl-alert);

  button.addEventListener(click, () => alert.show());

css:
  .alert-duration sl-alert {
    margin-top: var(--sl-spacing-medium);
  }
import { useState } from 'react';
import { SlAlert, SlButton, SlIcon } from '@teamshares/shoelace/dist/react';

const css = `
  .alert-duration sl-alert {
    margin-top: var(--sl-spacing-medium);
  }
`;

const App = () => {
  const [open, setOpen] = useState(false);

  return (
    <>
      <div className="alert-duration">
        <SlButton variant="primary" onClick={() => setOpen(true)}>
          Show Alert
        </SlButton>

        <SlAlert variant="primary" duration="3000" open={open} closable onSlAfterHide={() => setOpen(false)}>
          <SlIcon slot="icon" library="fa" name="fas-circle-info" />
          This alert will automatically hide itself after three seconds, unless you interact with it.
        </SlAlert>
      </div>

      <style>{css}</style>
    </>
  );
};

Toast Notifications

To display an alert as a toast notification, or “toast”, create the alert and call its toast() method. This will move the alert out of its position in the DOM and into the toast stack where it will be shown. Once dismissed, it will be removed from the DOM completely. To reuse a toast, store a reference to it and call toast() again later on.

You should always use the closable attribute so users can dismiss the notification. It’s also common to set a reasonable duration when the notification doesn’t require acknowledgement.

Primary Success Danger
We’ve simplified your login experience
You can now log in to both apps with one set of credentials.
Request submitted
Your request to issue 1,000 shares to Grace Hopper has been submitted.
Your settings couldn’t be updated
Please contact support for help with this issue.
<div class="alert-toast">
  <sl-button variant="primary">Primary</sl-button>
  <sl-button variant="success">Success</sl-button>
  <sl-button variant="danger">Danger</sl-button>

<sl-alert variant="primary" duration="3000" closable>
  <sl-icon slot="icon" library="fa" name="fas-circle-info"></sl-icon>
  <div slot="header">We’ve simplified your login experience</div>
  You can now log in to both apps with one set of credentials.
</sl-alert>

<sl-alert variant="success" duration="3000" closable>
  <sl-icon slot="icon" library="fa" name="fas-circle-check"></sl-icon>
  <div slot="header">Request submitted</div>
  Your request to issue 1,000 shares to Grace Hopper has been submitted.
</sl-alert>

<sl-alert variant="danger" duration="3000" closable>
  <sl-icon slot="icon" library="fa" name="fas-circle-exclamation"></sl-icon>
  <div slot="header">Your settings couldn’t be updated</div>
  Please <a class="ts-text-link" href="#">contact support</a> for help with this issue.
</sl-alert>
</div>

<script>
  const container = document.querySelector('.alert-toast');

  ['primary', 'success', 'danger'].map(variant => {
    const button = container.querySelector(`sl-button[variant="${variant}"]`);
    const alert = container.querySelector(`sl-alert[variant="${variant}"]`);

    button.addEventListener('click', () => alert.toast());
  });
</script>
div.alert-toast
  sl-button variant="primary" Primary
  sl-button variant="success" Success
  sl-button variant="warning" Warning
  sl-button variant="danger" Danger
  sl-alert variant="primary" duration="3000" closable="true"
    sl-icon slot="icon" library="fa" name="fas-circle-info"
    div slot="header" We’ve simplified your login experience!
    | You can now log in to both apps with one set of credentials.
  sl-alert variant="success" duration="3000" closable="true"
    sl-icon slot="icon" library="fa" name="fas-circle-check"
    div slot="header" Request submitted
    | Your request to issue 1,000 shares to Grace Hopper has been submitted.
  sl-alert variant="danger" duration="3000" closable="true"
    sl-icon slot="icon" library="fa" name="fas-circle-exclamation"
    div slot="header" Your settings couldn’t be updated
    | Please
    a class="ts-text-link" href="#" contact support
    | for help with this issue.

javascript:
  const container = document.querySelector(.alert-toast);

  [primary, success, danger].map(variant => {
    const button = container.querySelector(`sl-button[variant="${variant}"]`);
    const alert = container.querySelector(`sl-alert[variant="${variant}"]`);

    button.addEventListener(click, () => alert.toast());
  });
import { useRef } from 'react';
import { SlAlert, SlButton, SlIcon } from '@teamshares/shoelace/dist/react';

function showToast(alert) {
  alert.toast();
}

const App = () => {
  const primary = useRef(null);
  const success = useRef(null);
  const warning = useRef(null);
  const danger = useRef(null);

  return (
    <>
      <SlButton variant="primary" onClick={() => primary.current.toast()}>
        Primary
      </SlButton>

      <SlButton variant="success" onClick={() => success.current.toast()}>
        Success
      </SlButton>

      <SlButton variant="warning" onClick={() => warning.current.toast()}>
        Warning
      </SlButton>

      <SlButton variant="danger" onClick={() => danger.current.toast()}>
        Danger
      </SlButton>

      <SlAlert ref={primary} variant="primary" duration="3000" closable>
        <SlIcon slot="icon" library="fa" name="fas-circle-info" />
        <div slot="header">This is super informative</div>
        You can tell by how pretty the alert is.
      </SlAlert>

      <SlAlert ref={success} variant="success" duration="3000" closable>
        <SlIcon slot="icon" library="fa" name="fas-circle-check" />
        <div slot="header">Your changes have been saved</div>
        You can safely exit the app now.
      </SlAlert>

      <SlAlert ref={warning} variant="warning" duration="3000" closable>
        <SlIcon slot="icon" library="fa" name="fas-triangle-exclamation" />
        <div slot="header">Your session has ended</div>
        Please login again to continue.
      </SlAlert>

      <SlAlert ref={danger} variant="danger" duration="3000" closable>
        <SlIcon slot="icon" library="fa" name="fas-circle-exclamation" />
        <div slot="header">Your account has been deleted</div>
        We are very sorry to see you go!
      </SlAlert>
    </>
  );
};

Creating Toasts Imperatively

For convenience, you can create a utility that emits toast notifications with a function call rather than composing them in your HTML. To do this, generate the alert with JavaScript, append it to the body, and call the toast() method as shown in the example below.

Create Toast
<div class="alert-toast-wrapper">
  <sl-button variant="primary">Create Toast</sl-button>
</div>

<script>
  const container = document.querySelector('.alert-toast-wrapper');
  const button = container.querySelector('sl-button');
  let count = 0;

  // Always escape HTML for text arguments!
  function escapeHtml(html) {
    const div = document.createElement('div');
    div.textContent = html;
    return div.innerHTML;
  }

  // Custom function to emit toast notifications
  function notify(message, variant = 'primary', icon = 'fas-circle-info', duration = 3000) {
    const alert = Object.assign(document.createElement('sl-alert'), {
      variant,
      closable: true,
      duration: duration,
      innerHTML: `
        <sl-icon name="${icon}" library="fa" slot="icon"></sl-icon>
        ${escapeHtml(message)}
      `
    });

    document.body.append(alert);
    return alert.toast();
  }

  button.addEventListener('click', () => {
    notify(`This is custom toast #${++count}`);
  });
</script>
.alert-toast-wrapper
  sl-button[variant="primary"]
    | Create Toast

javascript:
  const container = document.querySelector('.alert-toast-wrapper');
  const button = container.querySelector('sl-button');
  let count = 0;

  // Always escape HTML for text arguments!
  function escapeHtml(html) {
    const div = document.createElement('div');
    div.textContent = html;
    return div.innerHTML;
  }

  // Custom function to emit toast notifications
  function notify(message, variant = 'primary', icon = 'fas-circle-info', duration = 3000) {
    const alert = Object.assign(document.createElement('sl-alert'), {
      variant,
      closable: true,
      duration: duration,
      innerHTML: `
        <sl-icon name="${icon}" library="fa" slot="icon"></sl-icon>
        ${escapeHtml(message)}
      `
    });

    document.body.append(alert);
    return alert.toast();
  }

  button.addEventListener('click', () => {
    notify(`This is custom toast #${++count}`);
  });

The Toast Stack

The toast stack is a fixed position singleton element created and managed internally by the alert component. It will be added and removed from the DOM as needed when toasts are shown. When more than one toast is visible, they will stack vertically in the toast stack.

By default, the toast stack is positioned at the bottom-right of the viewport. You can change its position by targeting .sl-toast-stack in your stylesheet. To make toasts appear at the top-left of the viewport, for example, use the following styles.

.sl-toast-stack {
  left: 0;
  right: auto;
}

Usage Guidelines

Using Icons in Alerts

Using Headers in Alerts

  • Do include a header (using slot="header") in the alert
  • Do keep the header short and scannable
  • Do use sentence case for headers
  • Don’t use a a period in the header, even if it’s a complete sentence

The Alert Message

  • Do keep the message as short as possible
  • Alert messages could contain plain text or a bulleted list, or even a button

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.1.0/cdn/components/alert/alert.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.1.0/cdn/components/alert/alert.js';

To import this component using a bundler:

import '@shoelace-style/shoelace/dist/components/alert/alert.js';

To import this component as a React component:

import SlAlert from '@shoelace-style/shoelace/dist/react/alert';

Slots

Name Description
(default) The alert’s main content.
icon An icon to show in the alert. Works best with <sl-icon>.
header An optional bold header for the alert.

Learn more about using slots.

Properties

Name Description Reflects Type Default
open Indicates whether or not the alert is open. You can toggle this attribute to show and hide the alert, or you can use the show() and hide() methods and this attribute will reflect the alert’s open state. boolean false
closable Enables a close button that allows the user to dismiss the alert. boolean false
variant The alert’s theme variant. 'primary' | 'success' | 'neutral' | 'warning' | 'danger' 'primary'
duration The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with the alert before it closes (e.g. moves the mouse over it), the timer will restart. Defaults to Infinity, meaning the alert will not close on its own. - Infinity
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
sl-show onSlShow Emitted when the alert opens. -
sl-after-show onSlAfterShow Emitted after the alert opens and all animations are complete. -
sl-hide onSlHide Emitted when the alert closes. -
sl-after-hide onSlAfterHide Emitted after the alert closes and all animations are complete. -

Learn more about events.

Methods

Name Description Arguments
show() Shows the alert. -
hide() Hides the alert -
toast() Displays the alert as a toast notification. This will move the alert out of its position in the DOM and, when dismissed, it will be removed from the DOM completely. By storing a reference to the alert, you can reuse it by calling this method again. The returned promise will resolve after the alert is hidden. -

Learn more about methods.

Parts

Name Description
base The component’s base wrapper.
icon The container that wraps the optional icon.
message The container that wraps the alert’s main content.
close-button The close button, an <sl-icon-button>.
close-button__base The close button’s exported base part.

Learn more about customizing CSS parts.

Animations

Name Description
alert.show The animation to use when showing the alert.
alert.hide The animation to use when hiding the alert.

Learn more about customizing animations.

Dependencies

This component automatically imports the following dependencies.

  • <sl-icon>
  • <sl-icon-button>