Search code examples
vue.jstoastprimevue

PrimeVue Toast displaying html tags


How can I implement displaying a link in a primevue toast message? I cannot use v-html directive and triple brackets do not work. Does anybody has another idea how to solve it?


Solution

  • A hacky way is to extends Toast component:

    Here a codesandbox : https://codesandbox.io/s/extend-primevue-toast-o5o1c?file=/src/CustomToastMessage.vue

    1. On your component

    Import your custom toast component where you need to call this.$toast:

    <template>
      <div>
        <CustomToast />
        <CustomToast position="top-left" group="tl" />
        <CustomToast position="bottom-left" group="bl" />
        <CustomToast position="bottom-right" group="br" />
    
        <div class="card">
          <Button @click="test" label="test" />
        </div>
      </div>
    </template>
    
    <script>
    import CustomToast from "./CustomToast.vue";
    export default {
      components: {
        CustomToast,
      },
      data() {
        return {
          messages: [],
        };
      },
      methods: {
        test() {
          this.$toast.add({
            severity: "success",
            summary: "Test",
            detail: "<b>Test Bold</b>",
          });
        },
      },
    };
    </script>
    

    2. CustomToast.vue (extend primevue toast)

    <template>
      <Teleport to="body">
        <div ref="container" :class="containerClass" v-bind="$attrs">
          <transition-group name="p-toast-message" tag="div" @enter="onEnter">
            <CustomToastMessage
              v-for="msg of messages"
              :key="msg.id"
              :message="msg"
              @close="remove($event)"
            />
          </transition-group>
        </div>
      </Teleport>
    </template>
    <script>
    import Toast from "primevue/toast/Toast.vue";
    import CustomToastMessage from "./CustomToastMessage.vue";
    
    export default {
      extends: Toast,
      components: {
        CustomToastMessage,
      },
    };
    </script>
    

    3. CustomToastMessage (extend primevue toastmessage)

    Add v-html where you want to have html

    <template>
      <div
        :class="containerClass"
        role="alert"
        aria-live="assertive"
        aria-atomic="true"
      >
        <div class="p-toast-message-content">
          <span :class="iconClass"></span>
          <div class="p-toast-message-text">
            <span class="p-toast-summary">{{ message.summary }}</span>
            <div class="p-toast-detail" v-html="message.detail"></div>
          </div>
          <button
            class="p-toast-icon-close p-link"
            @click="onCloseClick"
            v-if="message.closable !== false"
            type="button"
            v-ripple
          >
            <span class="p-toast-icon-close-icon pi pi-times"></span>
          </button>
        </div>
      </div>
    </template>
    
    <script>
    import ToastMessage from "primevue/toast/ToastMessage.vue";
    
    export default {
      extends: ToastMessage,
    };
    </script>