Skip to content

Custom Toast Component

You can customize the display of the toast by using your own Vue component.

Using you own Toast component

To use a custom Toast component, simply set the component option:

vue
<script setup>
import { useToaster } from '@bastien-j/vue-toaster'
import MyCustomToast from '@/components/MyCustomToast.vue' 

const toaster = useToaster()

function trigger() {
  toaster.info(
    'Should work!',
    { component: MyCustomToast } 
  )
}
</script>

<template>
  <button @click="trigger()">Trigger custom toast</button>
</template>
<script setup>
import { useToaster } from '@bastien-j/vue-toaster'
import MyCustomToast from '@/components/MyCustomToast.vue' 

const toaster = useToaster()

function trigger() {
  toaster.info(
    'Should work!',
    { component: MyCustomToast } 
  )
}
</script>

<template>
  <button @click="trigger()">Trigger custom toast</button>
</template>
vue
<script setup lang="ts">
import { computed } from 'vue'

import { StoredToast } from '@bastien-j/vue-toaster'

const props = defineProps<{
  toast: StoredToast
}>()

const classes = computed(() => {
  const options = props.toast.options
  const c = []
  if (options.type) c.push(`toast--${options.type}`)
  if (options.position) {
    if (['bottom-left', 'top-left'].includes(options.position)) c.push('toast--left')
    if (['bottom-right', 'top-right'].includes(options.position)) c.push('toast--right')
  }
  return c
})
</script>

<template>
  <div class="custom-toast" :class="classes">
    <div class="c-t-header">{{ toast.options.type }}</div>
    <div class="c-t-body">{{ toast.message }}</div>
  </div>
</template>

<style scoped lang="scss">
.custom-toast {
  align-self: center;
  border-radius: 8px;
  color: hsl(0, 0%, 100%);
  background-color: hsl(0, 0%, 30%);
  pointer-events: initial;
  overflow: hidden;

  .c-t-header {
    padding: 4px;
    background-color: hsl(0, 0%, 15%);
  }
  .c-t-body {
    padding: 8px;
  }

  &.toast--info {
    color: hsl(214, 100%, 64%);
  }
  &.toast--left {
    align-self: flex-start;
  }
  &.toast--right {
    align-self: flex-end;
  }
}
</style>
<script setup lang="ts">
import { computed } from 'vue'

import { StoredToast } from '@bastien-j/vue-toaster'

const props = defineProps<{
  toast: StoredToast
}>()

const classes = computed(() => {
  const options = props.toast.options
  const c = []
  if (options.type) c.push(`toast--${options.type}`)
  if (options.position) {
    if (['bottom-left', 'top-left'].includes(options.position)) c.push('toast--left')
    if (['bottom-right', 'top-right'].includes(options.position)) c.push('toast--right')
  }
  return c
})
</script>

<template>
  <div class="custom-toast" :class="classes">
    <div class="c-t-header">{{ toast.options.type }}</div>
    <div class="c-t-body">{{ toast.message }}</div>
  </div>
</template>

<style scoped lang="scss">
.custom-toast {
  align-self: center;
  border-radius: 8px;
  color: hsl(0, 0%, 100%);
  background-color: hsl(0, 0%, 30%);
  pointer-events: initial;
  overflow: hidden;

  .c-t-header {
    padding: 4px;
    background-color: hsl(0, 0%, 15%);
  }
  .c-t-body {
    padding: 8px;
  }

  &.toast--info {
    color: hsl(214, 100%, 64%);
  }
  &.toast--left {
    align-self: flex-start;
  }
  &.toast--right {
    align-self: flex-end;
  }
}
</style>

TIP

If your custom Toast component is registered globally, you can also pass its name instead of the Vue component.

TIP

Your custom Toast component will receive a StoredToast as a toast prop.

TIP

This option can be set globally when using the createToaster method.