I had this problem and I discovered that it's caused by declaring multiple ConfirmDialog components in DOM markup. For example if you add a confirm dialog to every component that uses it and then you happen to load 2+ components on the page at the same time, you will see 1 dialog for every <ConfirmDialog /> that exists on that page.

The solution is to only declare the ConfirmDialog once in your root Vue component and then every time you call it, only import the useConfirm function and then call the dialog with that.

For example:

App.vue

<script setup>
import ConfirmDialog from 'primevue/confirmdialog';
</script>

<template>
    <router-view></router-view>

    <ConfirmDialog />
</template>

Every other component:

<script setup>
import { useConfirm } from 'primevue/useconfirm';

const confirm = useConfirm();

const handleRemoveThing = () => {
    // bye
};

const onRemoveThing = () => {
    confirm.require({
        message: 'Are you sure you want to remove some thing?',
        header: 'Remove Thing',
        icon: 'icon-delete',
        rejectLabel: 'Cancel',
        acceptLabel: 'Remove',
        acceptClass: 'p-button-danger',
        accept: handleRemoveThing,
    });
};
</script>

<template>
    <div>
        <button @click="onRemoveThing">Remove</button>
    </div>
</template>
Answer from agm1984 on Stack Overflow
🌐
PrimeVue
primevue.org › confirmpopup
Vue Confirmation Popup Component
import { useConfirm } from "primevue/useconfirm"; const confirm = useConfirm(); ConfirmPopup is displayed by calling the require method of the $confirm instance by passing the options to customize the Popup.
🌐
PrimeVue
primevue.org › popover
PrimeVue | Vue UI Component Library
Popover component uses dialog role and since any attribute is passed to the root element you may define attributes like aria-label or aria-labelledby to describe the popup contents.
Discussions

ConfirmPopup: misplaced / missing popup on stopped click event
Describe the bug If the event which caused the popup to appear is stopped from propagating up to the root window, the popup is misplaced, or does not even appear, depending on whether the popup is ... More on github.com
🌐 github.com
8
February 16, 2024
ConfirmPopup also shows ConfirmDialog
On my Home page, in one of my components i use the ConfirmDialog to confirm user actions. And this works as expected. However in another component on the same page, i am trying to use the confirmPo... More on github.com
🌐 github.com
4
August 27, 2023
Primevue Dialog component.
You can toggle the reactive “visible” property however you would like. Just don’t set it equal to “false” until all confirmation conditions have been met. More on reddit.com
🌐 r/vuejs
3
2
June 17, 2024
PrimeVue ConfirmDialog Opens Multiple Times
I have a component from PrimeVue that works as it should, except for the fact that it opens multiple times when activated; for reference, I do the component multiple times More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › primefaces › primevue › issues › 5929
ConfirmPopup: misplaced / missing popup on stopped click event · Issue #5929 · primefaces/primevue
February 16, 2024 - Describe the bug If the event which caused the popup to appear is stopped from propagating up to the root window, the popup is misplaced, or does not even appear, depending on whether the popup is ...
Author   multun
🌐
GitHub
github.com › primefaces › primevue › issues › 4893
ConfirmPopup also shows ConfirmDialog · Issue #4893 · primefaces/primevue
August 27, 2023 - However in another component on the same page, i am trying to use the confirmPopup as it seems more appropriate in that component. When i click the button that calls confirm.require(), it shows the confirmPopup but also shows a confirm dialog. I am not sure what to do to prevent the confirm.require() for the popup from showing a ConfirmDialog.
Author   iampapagray
🌐
Reddit
reddit.com › r/vuejs › primevue dialog component.
r/vuejs on Reddit: Primevue Dialog component.
June 17, 2024 -

Hey everyone, Is it possible to add confirmation dialog based on conditions before closing a dialog? I have tried to add custom function but still the cancel button works.

<template>
    <Dialog v-model:visible="visible" modal :draggable="false" :style="{  width: '45rem' }">
        
        <template #header>
            <div class="flex justify-between items-center ml-5">
                <p class="font-semibold text-xl flex justify-center text-center">Item options</p>
            </div>
        </template>
        <template #closeicon>
            <i class="pi pi-times cursor-pointer p-dialog-header-icon" u/click="handleCancel" />
        </template>
        
        <div class="px-5 my-5">
            <div class="flex flex-col align-items-center gap-3 mb-5">
                <label for="listname" class="font-semibold w-6rem text-lg">Item name <span class="text-red-400">*</span></label>
                <InputText id="listname" class="flex-auto" v-model="listItemName" placeholder="list Item Name" autocomplete="off" />
            </div>
        </div>

        <div v-if="props.editableItem?.level != 3" class="flex align-items-center px-5 mt-5 ">
            <Checkbox v-model="containsublist" inputId="containsublist" name="sublist" value="sublist"  :binary="true"/>
            <label for="containsublist" class="ml-2">Contains sublist</label>
        </div>

        <!--  -->
        <div v-if="containsublist" class="mt-5">
            <div class="px-5">

                <div class="flex flex-col align-items-center gap-2 mb-3">
                    <label for="sublistitems" class="font-semibold w-6rem text-lg">Sublist items <span class="text-red-400">*</span></label>
                    <span class="text-sm text-surface-500">Multiple entries are allowed <br/> (Comma separated entries)</span>
                    
                    <span v-if="addClicked && sublistItems.length === 0" class="text-sm text-error"><i class="pi pi-exclamation-triangle text-error mr-2"></i>You should add items</span>
                    <Textarea id="sublistItems" v-model="sublistItem" rows="10" cols="30" placeholder="List item" :invalid="addClicked && sublistItem === ''"/>
                </div>

                <Button 
                    label="Add" 
                    icon="pi pi-plus" 
                    u/click="handleAdd" 
                    class="bg-success text-white hover:bg-success hover:border-success  my-2" /> 
     
        <!--  -->

        <div class="flex justify-center mt-5 mr-5">
            <Button label="Save" icon="pi pi-check" class="bg-success text-white hover:bg-success hover:border-success w-28" @click="handleEditItem" />
        </div>
        
        <ConfirmDialog group="headless">
            <template #container="{ message }">
                <div class="rounded-full p-3 mt-2">
                    <i class="pi pi-exclamation-triangle = mr-2"></i>
                    <span class="mt-2 font-poppins text-base text-surface-500">{{ message.message }}</span>
                    <!-- <div class="flex justify-end gap-2 mt-3">
                        <Button label="No" outlined @click="rejectCallback" severity="secondary" size="small" text></Button>
                        <Button label="Yes" @click="acceptCallback"  severity="success" size="small" ></Button>
                    </div> -->
                </div>
            </template>
        </ConfirmDialog>
    </Dialog>

</template>

<script setup>
  import { watch, ref } from "vue";
  import { useConfirm } from "primevue/useconfirm";
  import { useToast } from "primevue/usetoast";

  const confirm = useConfirm();
  const toast = useToast();
  const emit = defineEmits();

  const props= defineProps({
    editableItem: {
        type: Object,
        required: true
    },
    containsublist: {
        type: Boolean,
        required: true
    },
  });

  const sublistName = ref('');
  const sublistItem = ref('');
  const sublistItems = ref([]);
  const addClicked = ref(false);

  //   const containsublist = ref(false);
  const containsublist = ref(props.containsublist);
  const visible = ref(false);
  const listItemName = ref(props.editableItem.title);

  watch(() => props.editableItem, (newVal) => {
    listItemName.value = newVal.title;
  });

  const handleAdd = () => {
    addClicked.value = true;
    const items = sublistItem.value.split(/[\n,]+/)
                .map(item => item.trim())
                .filter(item => item !== '')
                .map(item => ({ name: item }));
    
    sublistItems.value = sublistItems.value.concat(items);
    
};

  const handleEditItem = () => {
    addClicked.value = true;
  
    if (sublistItems.value.length > 0){
        sublistItems.value = sublistItems.value.map((item, index) => {
            return { 
              id: index,
              title: item.name,
              isHovered: false,
              level: props.editableItem?.level + 1,
              sublists: [],
            }
        });
    

    const editedData = {
        'id':props.editableItem.id,
        'title':listItemName.value,
        'sublists':sublistItems.value,
    };

    emit('editItem',editedData)

    listItemName.value = '';
    sublistItem.value = '';
    sublistItems.value = [];
    containsublist.value = false;

    emit('cancel');
    };

  };

  const requireConfirmation = () => {
    confirm.require({
        group: 'headless',
        header: 'Are you sure you want to close the modal? Unsaved changes will be lost.',
        message: 'Please confirm to proceed.',
    });
};

  const handleCancel = () => {
  // Check if there are unsaved changes before closing
    //   if (hasUnsavedChanges()) {
    //     if (confirm("Are you sure you want to close the dialog? Unsaved changes will be lost.")) { // Use native confirm dialog
    //       emit('cancel');
    //       visible.value = false;
    //     }
    //   } else {
    //     emit('cancel');
    //     visible.value = false;
    //   }
    requireConfirmation();
    // emit('cancel');
    console.log('cancel hereeee')
    }

  const deleteItem = (data) => {
    sublistItems.value = sublistItems.value.filter(item => item.name !== data.name);
  };

  const emitOpenCreateListModal = () => {
    containsublist.value = false; 
    emit('openCreateListModal', props.editableItem); 
};

 const onRowReorder = (event) => {
    sublistItems.value = event.value;
  };
</script>

Any inputs would be helpful. Thank you.

Top answer
1 of 2
11

I had this problem and I discovered that it's caused by declaring multiple ConfirmDialog components in DOM markup. For example if you add a confirm dialog to every component that uses it and then you happen to load 2+ components on the page at the same time, you will see 1 dialog for every <ConfirmDialog /> that exists on that page.

The solution is to only declare the ConfirmDialog once in your root Vue component and then every time you call it, only import the useConfirm function and then call the dialog with that.

For example:

App.vue

<script setup>
import ConfirmDialog from 'primevue/confirmdialog';
</script>

<template>
    <router-view></router-view>

    <ConfirmDialog />
</template>

Every other component:

<script setup>
import { useConfirm } from 'primevue/useconfirm';

const confirm = useConfirm();

const handleRemoveThing = () => {
    // bye
};

const onRemoveThing = () => {
    confirm.require({
        message: 'Are you sure you want to remove some thing?',
        header: 'Remove Thing',
        icon: 'icon-delete',
        rejectLabel: 'Cancel',
        acceptLabel: 'Remove',
        acceptClass: 'p-button-danger',
        accept: handleRemoveThing,
    });
};
</script>

<template>
    <div>
        <button @click="onRemoveThing">Remove</button>
    </div>
</template>
2 of 2
2

As mentioned by others, the issue comes from having multiple instances rendered at the same time. Each instance listens globally, so if several are present in the DOM, they all open together.

To avoid this, you can use the group property on ConfirmDialog to target the specific dialog you want to open. This is especially useful if, like me, you have custom templates for each dialog.

You can see an example of this in the documentation: https://primevue.org/confirmdialog/#template

Here’s the basic idea:

<template>
    <div>
        <ConfirmDialog group="confirm-delete-stuff" />
        <button @click="deleteStuff">Delete</button>
    </div>
</template>

<script setup>
import { useConfirm } from 'primevue/useconfirm';

const confirm = useConfirm();

const deleteStuff = () => {
    confirm.require({
        group: 'confirm-delete-stuff',
        message: 'Are you sure you want to delete this stuff?',
        header: 'Delete stuff',
        rejectLabel: 'Cancel',
        acceptLabel: 'Remove',
        accept: () => {
            console.log('Remove stuff');
        },
    });
};
</script>


🌐
Stack Overflow
stackoverflow.com › questions › 79199683 › primevue-theme-preset-not-applied-in-chrome-extension-popup-using-vite
PrimeVue Theme Preset Not Applied in Chrome Extension Popup Using Vite - Stack Overflow
Here is a screenshot of the popup out of the box, as you can see the button doesn't have the theme style. ... import { createApp } from 'vue'; import App from './App.vue'; import PrimeVue from 'primevue/config'; import { definePreset } from '@primevue/themes'; import Lara from '@primevue/themes/lara'; const MyPreset = definePreset(Lara, { // Your customizations }); const app = createApp(App); app.use(PrimeVue, { preset: MyPreset }); app.mount('#app');
🌐
Primevue
v3.primevue.org › dropdown
PrimeVue Dropdown - Vue Select Component
If the editable option is enabled aria-autocomplete is also added. The relation between the combobox and the popup is created with aria-controls and aria-activedescendant attribute is used to instruct screen reader which option to read during keyboard navigation within the popup list.
Find elsewhere
🌐
GitHub
github.com › primefaces › primevue › issues › 4481
Menu: Remove focus from first item (in popup mode) · Issue #4481 · primefaces/primevue
September 20, 2023 - Describe the feature you would like to see added When using Menu in popup mode, the first item is receiving focus. See demo here: https://stackblitz.com/edit/prncz5-52f7xt I think the source elemen...
Author   omzy
🌐
PrimeVue
tailwind.primevue.org › popover
Tailwind CSS based Vue UI Component Library
Unstyled PrimeVuePowered by the Unstyled PrimeVue components with advanced customization options.
🌐
StackBlitz
stackblitz.com › edit › vue-primevue-toggle-menu-item
Toggle menu item in Prime Vue - StackBlitz
[vue3] Toggle menu item in PrimeVue - https://stackoverflow.com/q/69678230/6277151
🌐
GitHub
github.com › primefaces › primevue › issues › 4311
ConfirmPopup: Alignment fails when the target is a template ref · Issue #4311 · primefaces/primevue
August 21, 2023 - Alignment works correctly when the target comes from a click event (i.e. event.currentTarget as demonstrated here). However, alignment fails when the target is set using a Vue template ref. In that case, the popup appears in the top left corner of the page.
Author   danielshawellis
🌐
GitHub
github.com › primefaces › primevue › issues › 5890
Menu: Using the popup mode, the menu has a transparent background in dark mode. · Issue #5890 · primefaces/primevue
September 18, 2023 - Describe the bug The background of the Menu component, when using it in popup mode, is transparent when using a dark mode theme. It can be observed on the primevue website itself, thus I have not created a reproducer. It works in light m...
Published   Jun 14, 2024
🌐
GitHub
github.com › primefaces › primevue › issues › 7910
Menu component in popup mode closes unexpectedly on Tab after activation · Issue #7910 · primefaces/primevue
May 26, 2025 - Describe the bug Menu Component in popup-mode with a link tag inside (for example at #end-slot) Observed behavior: The focus briefly moves to the first link inside the popup, but the popup closes immediately afterward, likely due to focu...
Author   Theiaz
🌐
GitHub
github.com › primefaces › primevue › issues › 7241
Confirm Popup Through Custom Directive · Issue #7241 · primefaces/primevue
February 12, 2025 - Example: https://stackblitz.com/edit/primevue-4-vite-issue-template-oxg9ytnv Click "Button" for the popover
Author   hcancelik