---
title: Notify
desc: >-
  A Quasar plugin to display animated messages to users like notifications,
  toasts and snackbars.
---
Notify is a Quasar plugin that can display animated messages (floating above everything in your pages) to users in the form of a notification. They are useful for alerting the user of an event and can even engage the user through actions. Also known as a toast or snackbar.

## Notify API

### Methods

- `create(opts: object | string): Function`
  Creates a notification; Same as calling $q.notify(...)
  Params:
    - `opts` (object | string, required)
      Notification options
      Object shape:
        - `type` (string, optional)
          Optional type (that has been previously registered) or one of the out of the box ones ('positive', 'negative', 'warning', 'info', 'ongoing')
          Examples: `'negative'`, `'custom-type'`
        - `color` (string, optional)
          Color name for component from the Quasar Color Palette
          Examples: `'primary'`, `'teal'`, `'teal-10'`
        - `textColor` (string, optional)
          Overrides text color (if needed); Color name from the Quasar Color Palette
          Examples: `'primary'`, `'teal'`, `'teal-10'`
        - `message` (string, optional)
          The content of your message
          Examples: `'John Doe pinged you'`
        - `caption` (string, optional)
          The content of your optional caption
          Examples: `'5 minutes ago'`
        - `html` (boolean, optional)
          Render the message as HTML; This can lead to XSS attacks, so make sure that you sanitize the message first
        - `icon` (string, optional)
          Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
          Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
        - `iconColor` (string, optional) *(added v2.5.5)*
          Color name for component from the Quasar Color Palette
          Examples: `'primary'`, `'teal'`, `'teal-10'`
        - `iconSize` (string, optional) *(added v2.5.5)*
          Size in CSS units, including unit name
          Examples: `'16px'`, `'2rem'`
        - `avatar` (string, optional)
          URL to an avatar/image; Suggestion: use public folder
          Examples: `(public folder) 'img/something.png'`, `(relative path format) require('./my_img.jpg')`, `(URL) https://some-site.net/some-img.gif`
        - `spinner` (boolean | Component, optional)
          Useful for notifications that are updated; Displays a Quasar spinner instead of an avatar or icon; If value is Boolean 'true' then the default QSpinner is shown
          Examples: `true`, `QSpinnerBars`
        - `spinnerColor` (string, optional) *(added v2.5.5)*
          Color name for component from the Quasar Color Palette
          Examples: `'primary'`, `'teal'`, `'teal-10'`
        - `spinnerSize` (string, optional) *(added v2.5.5)*
          Size in CSS units, including unit name
          Examples: `'16px'`, `'2rem'`
        - `position` (string, optional), default `'bottom'`
          Window side/corner to stick to
          Accepts: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'center'`
        - `group` (boolean | string | number, optional), default `message + caption + multiline + actions labels + position`
          Override the auto generated group with custom one; Grouped notifications cannot be updated; String or number value inform this is part of a specific group, regardless of its options; When a new notification is triggered with same group name, it replaces the old one and shows a badge with how many times the notification was triggered
          Examples: `'my-group'`
        - `badgeColor` (string, optional)
          Color name for the badge from the Quasar Color Palette
          Examples: `'primary'`, `'teal'`, `'teal-10'`
        - `badgeTextColor` (string, optional)
          Color name for the badge text from the Quasar Color Palette
          Examples: `'primary'`, `'teal'`, `'teal-10'`
        - `badgePosition` (string, optional), default `top-left/top-right`
          Notification corner to stick badge to; If notification is on the left side then default is top-right otherwise it is top-left
          Accepts: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`
        - `badgeStyle` (string | any[] | object, optional)
          Style definitions to be attributed to the badge
          Examples: `'background-color: #ff0000'`, `{ backgroundColor: '#ff0000' }`
        - `badgeClass` (string | any[] | object, optional)
          Class definitions to be attributed to the badge
          Examples: `'my-special-class'`, `{ 'my-special-class': true }`
        - `progress` (boolean, optional)
          Show progress bar to detail when notification will disappear automatically (unless timeout is 0)
        - `progressClass` (string | any[] | object, optional)
          Class definitions to be attributed to the progress bar
          Examples: `'my-special-class'`, `{ 'my-special-class': true }`
        - `classes` (string, optional)
          Add CSS class(es) to the notification for easier customization
          Examples: `'my-notif-class'`
        - `attrs` (object, optional)
          Key-value for attributes to be set on the notification
          Examples: `{ role: 'alertdialog' }`
        - `timeout` (number, optional), default `5000`
          Amount of time to display (in milliseconds). Set to 0 to never dismiss automatically.
          Examples: `2500`
        - `actions` (any[], optional)
          Notification actions (buttons); Unless 'noDismiss' is true, clicking/tapping on the button will close the notification; Also check 'closeBtn' convenience prop
          Examples:
            - `[{ label: 'Show', handler: () => {}, 'aria-label': 'Button label' }, { icon: 'map', handler: () => {}, color: 'yellow' }, { label: 'Learn more', noDismiss: true, handler: () => {} }]`
          Object shape:
            - `handler` (Function, optional)
              Function to be executed when the button is clicked/tapped
              Examples: `() => { console.log('button clicked') }`
            - `noDismiss` (boolean, optional)
              Do not dismiss the notification when the button is clicked/tapped
            - `...` (any, optional)
              Any other QBtn prop except 'onClick' (use 'handler' instead)
              Examples: `label: 'Learn more'`, `color: 'primary'`
        - `onDismiss` (Function, optional)
          Function to call when notification gets dismissed
          Examples: `() => { console.log('Dismissed') }`
        - `closeBtn` (boolean | string, optional)
          Convenient way to add a dismiss button with a specific label, without using the 'actions' prop; If set to true, it uses a label according to the current Quasar language
          Examples: `'Close me'`
        - `multiLine` (boolean, optional)
          Put notification into multi-line mode; If this prop isn't used and more than one 'action' is specified then notification goes into multi-line mode by default
        - `ignoreDefaults` (boolean, optional)
          Ignore the default configuration (set by setDefaults()) for this instance only
  Returns: `Function` — Calling this function with no parameters hides the notification; When called with one Object parameter (the original notification must NOT be grouped), it updates the notification (specified properties are shallow merged with previous ones; note that group and position cannot be changed while updating and so they are ignored)
- `setDefaults(opts: object): void`
  Merge options into the default ones
  Params:
    - `opts` (object, required)
      Notification options except 'ignoreDefaults' (See 'opts' param of 'create()' for object properties)
- `registerType(typeName: string, typeOpts: object): void`
  Register a new type of notification (or override an existing one)
  Params:
    - `typeName` (string, required)
      Name of the type (to be used as 'type' prop later on)
      Examples: `'my-type'`
    - `typeOpts` (object, required)
      Notification options except 'ignoreDefaults' (See 'opts' param of 'create()' for object properties)

### Vue Injection

Accessible via `$q.notify` (e.g., `this.$q.notify` in Options API or `useQuasar().notify` in Composition API).

### quasar.config.js Options

Configuration key: `framework.config.notify`

- `type` (string, optional)
  Optional type (that has been previously registered) or one of the out of the box ones ('positive', 'negative', 'warning', 'info', 'ongoing')
  Examples: `'negative'`, `'custom-type'`
- `color` (string, optional)
  Color name for component from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `textColor` (string, optional)
  Overrides text color (if needed); Color name from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `message` (string, optional)
  The content of your message
  Examples: `'John Doe pinged you'`
- `caption` (string, optional)
  The content of your optional caption
  Examples: `'5 minutes ago'`
- `html` (boolean, optional)
  Render the message as HTML; This can lead to XSS attacks, so make sure that you sanitize the message first
- `icon` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `iconColor` (string, optional) *(added v2.5.5)*
  Color name for component from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `iconSize` (string, optional) *(added v2.5.5)*
  Size in CSS units, including unit name
  Examples: `'16px'`, `'2rem'`
- `avatar` (string, optional)
  URL to an avatar/image; Suggestion: use public folder
  Examples: `(public folder) 'img/something.png'`, `(relative path format) require('./my_img.jpg')`, `(URL) https://some-site.net/some-img.gif`
- `spinner` (boolean | Component, optional)
  Useful for notifications that are updated; Displays a Quasar spinner instead of an avatar or icon; If value is Boolean 'true' then the default QSpinner is shown
  Examples: `true`, `QSpinnerBars`
- `spinnerColor` (string, optional) *(added v2.5.5)*
  Color name for component from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `spinnerSize` (string, optional) *(added v2.5.5)*
  Size in CSS units, including unit name
  Examples: `'16px'`, `'2rem'`
- `position` (string, optional), default `'bottom'`
  Window side/corner to stick to
  Accepts: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'center'`
- `group` (boolean | string | number, optional), default `message + caption + multiline + actions labels + position`
  Override the auto generated group with custom one; Grouped notifications cannot be updated; String or number value inform this is part of a specific group, regardless of its options; When a new notification is triggered with same group name, it replaces the old one and shows a badge with how many times the notification was triggered
  Examples: `'my-group'`
- `badgeColor` (string, optional)
  Color name for the badge from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `badgeTextColor` (string, optional)
  Color name for the badge text from the Quasar Color Palette
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `badgePosition` (string, optional), default `top-left/top-right`
  Notification corner to stick badge to; If notification is on the left side then default is top-right otherwise it is top-left
  Accepts: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`
- `badgeStyle` (string | any[] | object, optional)
  Style definitions to be attributed to the badge
  Examples: `'background-color: #ff0000'`, `{ backgroundColor: '#ff0000' }`
- `badgeClass` (string | any[] | object, optional)
  Class definitions to be attributed to the badge
  Examples: `'my-special-class'`, `{ 'my-special-class': true }`
- `progress` (boolean, optional)
  Show progress bar to detail when notification will disappear automatically (unless timeout is 0)
- `progressClass` (string | any[] | object, optional)
  Class definitions to be attributed to the progress bar
  Examples: `'my-special-class'`, `{ 'my-special-class': true }`
- `classes` (string, optional)
  Add CSS class(es) to the notification for easier customization
  Examples: `'my-notif-class'`
- `attrs` (object, optional)
  Key-value for attributes to be set on the notification
  Examples: `{ role: 'alertdialog' }`
- `timeout` (number, optional), default `5000`
  Amount of time to display (in milliseconds). Set to 0 to never dismiss automatically.
- `actions` (any[], optional)
  Notification actions (buttons); Unless 'noDismiss' is true, clicking/tapping on the button will close the notification; Also check 'closeBtn' convenience prop
  Examples:
    - `[{ label: 'Show', handler: () => {}, 'aria-label': 'Button label' }, { icon: 'map', handler: () => {}, color: 'yellow' }, { label: 'Learn more', noDismiss: true, handler: () => {} }]`
  Object shape:
    - `handler` (Function, optional)
      Function to be executed when the button is clicked/tapped
      Examples: `() => { console.log('button clicked') }`
    - `noDismiss` (boolean, optional)
      Do not dismiss the notification when the button is clicked/tapped
    - `...` (any, optional)
      Any other QBtn prop except 'onClick' (use 'handler' instead, only possible with UI config)
      Examples: `label: 'Learn more'`, `color: 'primary'`
- `onDismiss` (Function, optional)
  Function to call when notification gets dismissed
  Examples: `() => { console.log('Dismissed') }`
- `closeBtn` (boolean | string, optional)
  Convenient way to add a dismiss button with a specific label, without using the 'actions' prop; If set to true, it uses a label according to the current Quasar language
  Examples: `'Close me'`
- `multiLine` (boolean, optional)
  Put notification into multi-line mode; If this prop isn't used and more than one 'action' is specified then notification goes into multi-line mode by default

## Installation

Add to `quasar.config.js`:

```js
framework: {
    plugins: [
      'Notify'
    ],
    config: {
      notify: { /* look at QuasarConfOptions from the API card */ }
    }
}
```

## Usage

### Basic

```js
import { Notify } from 'quasar'

Notify.create('Danger, Will Robinson! Danger!')
// or with a config object:
Notify.create({
  message: 'Danger, Will Robinson! Danger!'
})
```

```js
import { useQuasar } from 'quasar'

setup () {
  const $q = useQuasar()

  $q.notify('Message')
  // or with a config object:
  $q.notify({...})
}
```

### Basic

```vue
<template>
  <div class="q-pa-md">
    <q-btn color="purple" @click="showNotif" label="Show Notification" />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  $q.notify({
    message: 'Jim pinged you.',
    color: 'purple'
  })
}
</script>
```

> [!TIP]
> If you define any actions, the notification will automatically be dismissed when the user picks it.

### With caption

```vue
<template>
  <div class="q-pa-md">
    <q-btn color="purple" @click="showNotif" label="Show with caption" />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  $q.notify({
    message: 'Jim pinged you.',
    caption: '5 minutes ago',
    color: 'secondary'
  })
}
</script>
```

### With icon, avatar or spinner

```vue
<template>
  <div class="q-pa-md">
    <q-btn color="purple" @click="showNotif" label="Show Notification" />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  $q.notify({
    message: 'Jim pinged you.',
    icon: 'announcement'
  })
}
</script>
```

### With avatar

```vue
<template>
  <div class="q-pa-md">
    <q-btn color="purple" @click="showNotif" label="Show Notification" />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  $q.notify({
    message: 'Jim pinged you.',
    color: 'purple',
    avatar: 'https://cdn.quasar.dev/img/boy-avatar.png'
  })
}
</script>
```

### With spinner

```vue
<template>
  <div class="q-pa-md">
    <div class="row q-gutter-sm">
      <q-btn color="purple" @click="showDefault" label="Default spinner" />
      <q-btn color="purple" @click="showCustom" label="Custom spinner" />
    </div>
  </div>
</template>

<script setup>
import { QSpinnerGears, useQuasar } from 'quasar'

const $q = useQuasar()

function showDefault() {
  $q.notify({
    spinner: true,
    message: 'Please wait...',
    timeout: 2000
  })
}

function showCustom() {
  $q.notify({
    spinner: QSpinnerGears,
    message: 'Working...',
    timeout: 2000
  })
}
</script>
```

### With actions

```vue
<template>
  <div class="q-pa-md">
    <q-btn color="purple" @click="showNotif" label="Show Notifications" />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  $q.notify({
    message: 'Jim just pinged you.',
    color: 'primary',
    avatar: 'https://cdn.quasar.dev/img/boy-avatar.png',
    actions: [
      {
        label: 'Dismiss',
        color: 'white',
        handler: () => {
          /* ... */
        }
      }
    ]
  })

  $q.notify({
    message: 'Jim just pinged you.',
    color: 'primary',
    avatar: 'https://cdn.quasar.dev/img/boy-avatar.png',
    actions: [
      {
        label: 'Reply',
        color: 'yellow',
        handler: () => {
          /* ... */
        }
      },
      {
        label: 'Dismiss',
        color: 'white',
        handler: () => {
          /* ... */
        }
      }
    ]
  })

  $q.notify({
    message: 'Jim just pinged you.',
    color: 'primary',
    avatar: 'https://cdn.quasar.dev/img/boy-avatar.png',
    actions: [
      {
        icon: 'close',
        color: 'white',
        round: true,
        handler: () => {
          /* ... */
        }
      }
    ]
  })
}
</script>
```

### Multiline

```vue
<template>
  <div class="q-pa-md">
    <q-btn color="purple" @click="showNotif" label="Show Notification" />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  $q.notify({
    message:
      'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Hic quisquam non ad sit assumenda consequuntur esse inventore officia. Corrupti reiciendis impedit vel, fugit odit quisquam quae porro exercitationem eveniet quasi.',
    color: 'primary',
    multiLine: true,
    avatar: 'https://cdn.quasar.dev/img/boy-avatar.png',
    actions: [
      {
        label: 'Reply',
        color: 'yellow',
        handler: () => {
          /* ... */
        }
      }
    ]
  })
}
</script>
```

### Positioning

```vue
<template>
  <div class="q-pa-md q-gutter-y-sm column items-center">
    <div>
      <div class="row q-gutter-sm">
        <q-btn round size="sm" color="secondary" @click="showNotif('top-left')">
          <q-icon name="arrow_back" class="rotate-45" />
        </q-btn>
        <q-btn round size="sm" color="accent" @click="showNotif('top')">
          <q-icon name="arrow_upward" />
        </q-btn>
        <q-btn
          round
          size="sm"
          color="secondary"
          @click="showNotif('top-right')"
        >
          <q-icon name="arrow_upward" class="rotate-45" />
        </q-btn>
      </div>
    </div>

    <div>
      <div class="row q-gutter-sm">
        <div>
          <q-btn round size="sm" color="accent" @click="showNotif('left')">
            <q-icon name="arrow_back" />
          </q-btn>
        </div>
        <div>
          <q-btn round size="sm" color="accent" @click="showNotif('center')">
            <q-icon name="fullscreen_exit" />
          </q-btn>
        </div>
        <div>
          <q-btn round size="sm" color="accent" @click="showNotif('right')">
            <q-icon name="arrow_forward" />
          </q-btn>
        </div>
      </div>
    </div>

    <div>
      <div class="row q-gutter-sm">
        <div>
          <q-btn
            round
            size="sm"
            color="secondary"
            @click="showNotif('bottom-left')"
          >
            <q-icon name="arrow_forward" class="rotate-135" />
          </q-btn>
        </div>
        <div>
          <q-btn round size="sm" color="accent" @click="showNotif('bottom')">
            <q-icon name="arrow_downward" />
          </q-btn>
        </div>
        <div>
          <q-btn
            round
            size="sm"
            color="secondary"
            @click="showNotif('bottom-right')"
          >
            <q-icon name="arrow_forward" class="rotate-45" />
          </q-btn>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const alerts = [
  // ...
]

const $q = useQuasar()

function showNotif(position) {
  const { color, textColor, multiLine, icon, message, avatar } =
    alerts[Math.floor(Math.random(alerts.length) * 10) % alerts.length]
  const random = Math.random() * 100

  const twoActions = random > 70
  const buttonColor = color ? 'white' : void 0

  $q.notify({
    color,
    textColor,
    icon: random > 30 ? icon : null,
    message,
    position,
    avatar,
    multiLine,
    actions: twoActions
      ? [
          {
            label: 'Reply',
            color: buttonColor,
            handler: () => {
              /* console.log('wooow') */
            }
          },
          {
            label: 'Dismiss',
            color: 'yellow',
            handler: () => {
              /* console.log('wooow') */
            }
          }
        ]
      : random > 40
        ? [
            {
              label: 'Reply',
              color: buttonColor,
              handler: () => {
                /* console.log('wooow') */
              }
            }
          ]
        : null,
    timeout: Math.random() * 5000 + 3000
  })
}
</script>
```

> [!TIP]
> For a full list of options, check the API section.

### Grouping

Each notification has an underlying unique group which is computed out of the message + caption + multiLine + actions labels + position. When multiple notifications get triggered with the same group, instead of showing all of them and flooding the view, only the first one remains on screen along with a badge. The badge content represents the number of times that the same notification has been triggered (and with same position) since the first one appeared on screen.

However, if you wish to disable this behavior, specify `group: false`. In the example below, the first button triggers the same notification twice each time is clicked. The second button has grouping disabled. The third button, however, has a custom group name so each subsequent notification replaces the old one and increments the badge number.

### Grouping

```vue
<template>
  <div class="q-pa-md">
    <div class="row q-gutter-sm">
      <q-btn no-caps color="teal" @click="triggerTwice" label="Trigger twice" />
      <q-btn
        no-caps
        color="teal"
        @click="triggerNoGroupingTwice"
        label="Trigger twice (no grouping)"
      />
      <q-btn
        no-caps
        color="teal"
        @click="triggerTwiceCustomGroup"
        label="Trigger twice (custom group)"
      />
    </div>
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function triggerTwice() {
  $q.notify({
    message: 'Jim pinged you.',
    color: 'purple'
  })

  $q.notify({
    message: 'Jim pinged you.',
    color: 'purple'
  })
}

function triggerNoGroupingTwice() {
  $q.notify({
    group: false,
    message: 'Jim pinged you.',
    color: 'purple'
  })

  $q.notify({
    group: false,
    message: 'Jim pinged you.',
    color: 'purple'
  })
}

function triggerTwiceCustomGroup() {
  $q.notify({
    group: 'my-group',
    message: 'Jim pinged you.',
    color: 'purple'
  })

  // same group as the previous one,
  // so it will replace it and
  // increment the badge number:
  $q.notify({
    group: 'my-group',
    message: 'Jack has messaged you.',
    color: 'primary'
  })
}
</script>
```

### Custom badge

```vue
<template>
  <div class="q-pa-md">
    <q-btn
      no-caps
      color="primary"
      @click="triggerTwice"
      label="Trigger twice with custom badge"
    />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function triggerTwice() {
  $q.notify({
    message: 'Jim pinged you.',
    color: 'purple',
    badgeColor: 'yellow',
    badgeTextColor: 'dark',
    badgeClass: 'shadow-3 glossy my-badge-class'
  })

  $q.notify({
    message: 'Jim pinged you.',
    color: 'purple',
    badgeColor: 'yellow',
    badgeTextColor: 'dark',
    badgeClass: 'shadow-3 glossy my-badge-class'
  })
}
</script>

<style lang="sass">
.my-badge-class
  border: 1px solid #ccc
</style>
```

### Timeout progress

Should you wish, there is a way to tell the user when the notification will disappear from the screen. That's for the cases when timeout is not set to 0.

### Timeout progress

```vue
<template>
  <div class="q-pa-md">
    <q-btn
      no-caps
      color="purple"
      @click="showNotifs"
      label="Show timeout progress"
    />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotifs() {
  $q.notify({
    progress: true,
    message:
      'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Hic quisquam non ad sit assumenda consequuntur esse inventore officia. Corrupti reiciendis impedit vel, fugit odit quisquam quae porro exercitationem eveniet quasi.',
    color: 'primary',
    multiLine: true,
    avatar: 'https://cdn.quasar.dev/img/boy-avatar.png',
    actions: [
      {
        label: 'Reply',
        color: 'yellow',
        handler: () => {
          /* ... */
        }
      }
    ]
  })

  setTimeout(() => {
    $q.notify({
      progress: true,
      message: 'Jim emailed you.',
      icon: 'mail',
      color: 'white',
      textColor: 'primary'
    })
  }, 2000)

  setTimeout(() => {
    $q.notify({
      progress: true,
      message: 'Jim pinged you.',
      color: 'purple',
      avatar: 'https://cdn.quasar.dev/img/boy-avatar.png',
      actions: [
        {
          label: 'Reply',
          color: 'yellow',
          handler: () => {
            /* ... */
          }
        }
      ]
    })
  }, 3200)
}
</script>
```

### Updatable notifications

Should you have an ongoing process and you want to inform the user of its progress without blocking what he is currently doing, then you can generate an updatable notification. It's useful to also show a spinner while at it.

Please note in the example below that we are explicitly setting "group: false" (because only non-grouped notifications can be updated) and "timeout: 0" (because we want to be in full control when the notification will be dismissed).

### Updatable

```vue
<template>
  <div class="q-pa-md">
    <q-btn
      no-caps
      color="purple"
      @click="showNotif"
      label="Show updatable notification"
    />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  const notif = $q.notify({
    group: false, // required to be updatable
    timeout: 0, // we want to be in control when it gets dismissed
    spinner: true,
    message: 'Uploading file...',
    caption: '0%'
  })

  // we simulate some progress here...
  let percentage = 0
  const interval = setInterval(() => {
    percentage = Math.min(100, percentage + Math.floor(Math.random() * 22))

    // we update the dialog
    notif({
      caption: `${percentage}%`
    })

    // if we are done...
    if (percentage === 100) {
      notif({
        icon: 'done', // we add an icon
        spinner: false, // we reset the spinner setting so the icon can be displayed
        message: 'Uploading done!',
        timeout: 2500 // we will timeout it in 2.5s
      })
      clearInterval(interval)
    }
  }, 500)
}
</script>
```

### Predefined types

There are four predefined types out of the box that you can use: "positive", "negative", "warning" and "info":

### Out of the box types

```vue
<template>
  <div class="q-pa-md">
    <div class="row q-gutter-sm">
      <q-btn
        no-caps
        unelevated
        color="positive"
        @click="triggerPositive"
        label="Trigger 'positive'"
      />
      <q-btn
        no-caps
        unelevated
        color="negative"
        @click="triggerNegative"
        label="Trigger 'negative'"
      />
      <q-btn
        no-caps
        unelevated
        color="warning"
        text-color="dark"
        @click="triggerWarning"
        label="Trigger 'warning'"
      />
      <q-btn
        no-caps
        unelevated
        color="info"
        @click="triggerInfo"
        label="Trigger 'info'"
      />
      <q-btn
        no-caps
        unelevated
        color="grey-8"
        @click="triggerOngoing"
        label="Trigger 'ongoing'"
      />
    </div>
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function triggerPositive() {
  $q.notify({
    type: 'positive',
    message: 'This is a "positive" type notification.'
  })
}

function triggerNegative() {
  $q.notify({
    type: 'negative',
    message: 'This is a "negative" type notification.'
  })
}

function triggerWarning() {
  $q.notify({
    type: 'warning',
    message: 'This is a "warning" type notification.'
  })
}

function triggerInfo() {
  $q.notify({
    type: 'info',
    message: 'This is a "info" type notification.'
  })
}

function triggerOngoing() {
  // we need to get the notification reference
  // otherwise it will never get dismissed ('ongoing' type has timeout 0)
  const notif = $q.notify({
    type: 'ongoing',
    message: 'Looking up the search terms...'
  })

  // simulate delay
  setTimeout(() => {
    notif({
      type: 'positive',
      message: 'Found the results that you were looking for',
      timeout: 1000
    })
  }, 4000)
}
</script>
```

Furthermore, you can register your own types or even override the predefined ones. The best place to do this would be in a [@quasar/app-vite Boot File](../quasar-cli-vite/boot-files.md).

### Custom type

```vue
<template>
  <div class="q-pa-md">
    <div class="row q-gutter-sm">
      <q-btn
        no-caps
        color="brown"
        @click="triggerCustomRegisteredType1"
        label="Trigger 1"
      />
      <q-btn
        no-caps
        color="primary"
        @click="triggerCustomRegisteredType2"
        label="Trigger 2"
      />
    </div>
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

/**
 * The reason we have this here
 * is that the type needs to be
 * registered before using it.
 *
 * The best place would be a boot file instead
 * of a .vue file, otherwise it'll keep on
 * registering it every time your component
 * gets to be used :)
 */

$q.notify.registerType('my-notif', {
  icon: 'announcement',
  progress: true,
  color: 'brown',
  textColor: 'white',
  classes: 'glossy'
})

function triggerCustomRegisteredType1() {
  $q.notify({
    type: 'my-notif',
    message: 'This notification is using a custom type.'
  })
}

function triggerCustomRegisteredType2() {
  // this one overrides some of the original
  // options of the "my-notif" registered type
  $q.notify({
    type: 'my-notif',
    icon: 'contactless',
    message: 'This notification is using a custom type.',
    caption: "It overrides the type's default icon and color.",
    color: 'primary'
  })
}
</script>
```

```js
import { Notify } from 'quasar'

Notify.registerType('my-notif', {
  icon: 'announcement',
  progress: true,
  color: 'brown',
  textColor: 'white',
  classes: 'glossy'
})
```

### Using HTML

You can use HTML on message if you specify the `html: true` prop. **Please note that this can lead to XSS attacks**, so make sure that you sanitize the message by yourself.

### Unsafe HTML message

```vue
<template>
  <div class="q-pa-md">
    <q-btn
      no-caps
      color="purple"
      @click="showNotif"
      label="Show HTML Notification"
    />
  </div>
</template>

<script setup>
import { useQuasar } from 'quasar'

const $q = useQuasar()

function showNotif() {
  $q.notify({
    message:
      '<em>I can</em> <span style="color: red">use</span> <strong>HTML</strong>',
    html: true
  })
}
</script>
```

### Setting attributes

You can set custom HTML attributes on the notification itself by setting the `attrs` Object property. For individual notification actions, you can directly pass them just like any other prop.

```js
import { useQuasar } from 'quasar'

setup () {
  const $q = useQuasar()

  $q.notify({
    // ...

    attrs: {
      // for the notification itself:
      role: 'alertdialog'
    },

    actions: [
      {
        icon: 'close',
        // for individual action (button):
        'aria-label': 'Dismiss'
      }
    ]
  })
}
```

### Programmatically closing

Notifications are meant to be dismissed only by the user, however for exceptional cases you can do it programmatically. Especially useful when you set indefinite timeout (0).

```js
const dismiss = $q.notify({...})
...
dismiss()
```

### Setting defaults

There are two ways of setting default configuration that will apply to all Notifications: through quasar.config file > framework > config > notify Object (see Installation section) or programmatically (see below).

```js
// quasar.config file
framework: {
  config: {
    notify: {
      // the config file cannot import components,
      // so a spinner is referred to by its name
      spinner: 'QSpinnerHourglass'
      // ...other Notify options
    }
  }
}
```

We'll describe setting the defaults through a [@quasar/app-vite Boot File](../quasar-cli-vite/boot-files.md) (works the same anywhere in your code, but a boot file ensures this is run before your app starts):

First we create the boot file. Let's name it "notify-defaults.js".

```bash
quasar new boot notify-defaults [--format ts]
```

Add the created notify-defaults.js file to the boot array in the `/quasar.config` file:

```js
import { defineConfig } from '#q-app'

export default defineConfig(ctx => {
  return {
    // ...
    boot: ['notify-defaults']
    // ...
  }
})
```

We then edit the newly created `/src/boot/notify-defaults.js`:

```ts
import { Notify } from 'quasar'

Notify.setDefaults({
  timeout: 2500,
  textColor: 'white',
  actions: [{ icon: 'close', color: 'white' }],
  position: 'top-right'
})
```

> [!WARNING]
> You can only set default `actions` through this method. Specifying `actions` with handlers in the `/quasar.config` file cannot and will NOT work.

We could also set the defaults in some Vue file:

```js
import { useQuasar } from 'quasar'

setup () {
  const $q = useQuasar()

  $q.notify.setDefaults({
    position: 'top-right',
    timeout: 2500,
    textColor: 'white',
    actions: [{ icon: 'close', color: 'white' }]
  })
}
```
