diff --git a/CRM/Contact/Form/Task/Delete.php b/CRM/Contact/Form/Task/Delete.php
index 8a3914822d972ee0f2293c01bfa2742cf01837a5..054f2cf6dad87794d090a16d08ade174b8e797b5 100644
--- a/CRM/Contact/Form/Task/Delete.php
+++ b/CRM/Contact/Form/Task/Delete.php
@@ -65,8 +65,8 @@ class CRM_Contact_Form_Task_Delete extends CRM_Contact_Form_Task {
 
     // sort out whether it’s a delete-to-trash, delete-into-oblivion or restore (and let the template know)
     $values = $this->controller->exportValues();
-    $this->_skipUndelete = (CRM_Core_Permission::check('access deleted contacts') and (CRM_Utils_Request::retrieve('skip_undelete', 'Boolean', $this) or ($values['task'] ?? NULL) == CRM_Contact_Task::DELETE_PERMANENTLY));
-    $this->_restore = (CRM_Utils_Request::retrieve('restore', 'Boolean', $this) or ($values['task'] ?? NULL) == CRM_Contact_Task::RESTORE);
+    $this->_skipUndelete = (CRM_Core_Permission::check('access deleted contacts') and (CRM_Utils_Request::retrieve('skip_undelete', 'Boolean', $this) or ($values['task'] ?? NULL) == CRM_Contact_Task::DELETE_PERMANENTLY) || in_array('delete-permanently', $this->urlPath));
+    $this->_restore = (CRM_Utils_Request::retrieve('restore', 'Boolean', $this) or ($values['task'] ?? NULL) == CRM_Contact_Task::RESTORE or in_array('restore-contact', $this->urlPath));
 
     if ($this->_restore && !CRM_Core_Permission::check('access deleted contacts')) {
       CRM_Core_Error::statusBounce(ts('You do not have permission to access this contact.'));
@@ -78,10 +78,6 @@ class CRM_Contact_Form_Task_Delete extends CRM_Contact_Form_Task {
     $this->assign('trash', Civi::settings()->get('contact_undelete') and !$this->_skipUndelete);
     $this->assign('restore', $this->_restore);
 
-    if ($this->_restore) {
-      $this->setTitle(ts('Restore Contact'));
-    }
-
     if ($cid) {
       if (!CRM_Contact_BAO_Contact_Permission::allow($cid, CRM_Core_Permission::EDIT)) {
         CRM_Core_Error::statusBounce(ts('You do not have permission to delete this contact. Note: you can delete contacts if you can edit them.'));
@@ -99,6 +95,10 @@ class CRM_Contact_Form_Task_Delete extends CRM_Contact_Form_Task {
       parent::preProcess();
     }
 
+    if ($this->_restore) {
+      $this->setTitle(ts('Restore Contact'));
+    }
+
     $this->_sharedAddressMessage = $this->get('sharedAddressMessage');
     if (!$this->_restore && !$this->_sharedAddressMessage) {
       // we check for each contact for shared contact address
diff --git a/CRM/Contact/Task.php b/CRM/Contact/Task.php
index 83bbe220d53e4d23eb5147826199bffa89c6e6d1..d42c1f498af247f5f53c080f384a67bd069b9518 100644
--- a/CRM/Contact/Task.php
+++ b/CRM/Contact/Task.php
@@ -153,10 +153,12 @@ class CRM_Contact_Task extends CRM_Core_Task {
         self::RESTORE => [
           'title' => ts('Restore contacts from trash'),
           'class' => 'CRM_Contact_Form_Task_Delete',
+          'url' => 'civicrm/task/restore-contact',
           'result' => FALSE,
         ],
         self::DELETE_PERMANENTLY => [
           'title' => ts('Delete permanently'),
+          'url' => 'civicrm/task/delete-permanently',
           'class' => 'CRM_Contact_Form_Task_Delete',
           'result' => FALSE,
         ],
diff --git a/CRM/Core/xml/Menu/Misc.xml b/CRM/Core/xml/Menu/Misc.xml
index 1d3ea602cc03757b43648f430e668f8a68f50505..7dcf9ab9ad414637b13eb49c50a49540a5e74776 100644
--- a/CRM/Core/xml/Menu/Misc.xml
+++ b/CRM/Core/xml/Menu/Misc.xml
@@ -284,4 +284,14 @@
     <page_callback>CRM_Note_Form_Note</page_callback>
     <access_arguments>access CiviCRM</access_arguments>
   </item>
+  <item>
+    <path>civicrm/task/delete-permanently</path>
+    <page_callback>CRM_Contact_Form_Task_Delete</page_callback>
+    <access_arguments>access deleted contacts</access_arguments>
+  </item>
+  <item>
+    <path>civicrm/task/restore-contact</path>
+    <page_callback>CRM_Contact_Form_Task_Delete</page_callback>
+    <access_arguments>access CiviCRM</access_arguments>
+  </item>
 </menu>