diff --git a/web_src/js/features/repo-projects.js b/web_src/js/features/repo-projects.js
index 5a2a7e72e..5dd80b29b 100644
--- a/web_src/js/features/repo-projects.js
+++ b/web_src/js/features/repo-projects.js
@@ -2,8 +2,7 @@ import $ from 'jquery';
 import {useLightTextOnBackground} from '../utils/color.js';
 import tinycolor from 'tinycolor2';
 import {createSortable} from '../modules/sortable.js';
-
-const {csrfToken} = window.config;
+import {POST, DELETE, PUT} from '../modules/fetch.js';
 
 function updateIssueCount(cards) {
   const parent = cards.parentElement;
@@ -11,22 +10,23 @@ function updateIssueCount(cards) {
   parent.getElementsByClassName('project-column-issue-count')[0].textContent = cnt;
 }
 
-function createNewColumn(url, columnTitle, projectColorInput) {
-  $.ajax({
-    url,
-    data: JSON.stringify({title: columnTitle.val(), color: projectColorInput.val()}),
-    headers: {
-      'X-Csrf-Token': csrfToken,
-    },
-    contentType: 'application/json',
-    method: 'POST',
-  }).done(() => {
+async function createNewColumn(url, columnTitle, projectColorInput) {
+  try {
+    await POST(url, {
+      data: {
+        title: columnTitle.val(),
+        color: projectColorInput.val(),
+      },
+    });
+  } catch (error) {
+    console.error(error);
+  } finally {
     columnTitle.closest('form').removeClass('dirty');
     window.location.reload();
-  });
+  }
 }
 
-function moveIssue({item, from, to, oldIndex}) {
+async function moveIssue({item, from, to, oldIndex}) {
   const columnCards = to.getElementsByClassName('issue-card');
   updateIssueCount(from);
   updateIssueCount(to);
@@ -38,18 +38,14 @@ function moveIssue({item, from, to, oldIndex}) {
     })),
   };
 
-  $.ajax({
-    url: `${to.getAttribute('data-url')}/move`,
-    data: JSON.stringify(columnSorting),
-    headers: {
-      'X-Csrf-Token': csrfToken,
-    },
-    contentType: 'application/json',
-    type: 'POST',
-    error: () => {
-      from.insertBefore(item, from.children[oldIndex]);
-    },
-  });
+  try {
+    await POST(`${to.getAttribute('data-url')}/move`, {
+      data: columnSorting,
+    });
+  } catch (error) {
+    console.error(error);
+    from.insertBefore(item, from.children[oldIndex]);
+  }
 }
 
 async function initRepoProjectSortable() {
@@ -67,20 +63,21 @@ async function initRepoProjectSortable() {
     ghostClass: 'card-ghost',
     delayOnTouchOnly: true,
     delay: 500,
-    onSort: () => {
+    onSort: async () => {
       boardColumns = mainBoard.getElementsByClassName('project-column');
       for (let i = 0; i < boardColumns.length; i++) {
         const column = boardColumns[i];
         if (parseInt($(column).data('sorting')) !== i) {
-          $.ajax({
-            url: $(column).data('url'),
-            data: JSON.stringify({sorting: i, color: rgbToHex($(column).css('backgroundColor'))}),
-            headers: {
-              'X-Csrf-Token': csrfToken,
-            },
-            contentType: 'application/json',
-            method: 'PUT',
-          });
+          try {
+            await PUT($(column).data('url'), {
+              data: {
+                sorting: i,
+                color: rgbToHex($(column).css('backgroundColor')),
+              },
+            });
+          } catch (error) {
+            console.error(error);
+          }
         }
       }
     },
@@ -118,18 +115,19 @@ export function initRepoProject() {
       setLabelColor(projectHeader, rgbToHex(boardColumn.css('backgroundColor')));
     }
 
-    $(this).find('.edit-project-column-button').on('click', function (e) {
+    $(this).find('.edit-project-column-button').on('click', async function (e) {
       e.preventDefault();
 
-      $.ajax({
-        url: $(this).data('url'),
-        data: JSON.stringify({title: projectTitleInput.val(), color: projectColorInput.val()}),
-        headers: {
-          'X-Csrf-Token': csrfToken,
-        },
-        contentType: 'application/json',
-        method: 'PUT',
-      }).done(() => {
+      try {
+        await PUT($(this).data('url'), {
+          data: {
+            title: projectTitleInput.val(),
+            color: projectColorInput.val(),
+          },
+        });
+      } catch (error) {
+        console.error(error);
+      } finally {
         projectTitleLabel.text(projectTitleInput.val());
         projectTitleInput.closest('form').removeClass('dirty');
         if (projectColorInput.val()) {
@@ -137,7 +135,7 @@ export function initRepoProject() {
         }
         boardColumn.attr('style', `background: ${projectColorInput.val()}!important`);
         $('.ui.modal').modal('hide');
-      });
+      }
     });
   });
 
@@ -146,19 +144,16 @@ export function initRepoProject() {
     const showButton = $(boardColumn).find('.default-project-column-show');
     const commitButton = $(this).find('.actions > .ok.button');
 
-    $(commitButton).on('click', (e) => {
+    $(commitButton).on('click', async (e) => {
       e.preventDefault();
 
-      $.ajax({
-        method: 'POST',
-        url: $(showButton).data('url'),
-        headers: {
-          'X-Csrf-Token': csrfToken,
-        },
-        contentType: 'application/json',
-      }).done(() => {
+      try {
+        await POST($(showButton).data('url'));
+      } catch (error) {
+        console.error(error);
+      } finally {
         window.location.reload();
-      });
+      }
     });
   });
 
@@ -167,19 +162,16 @@ export function initRepoProject() {
     const deleteColumnButton = deleteColumnModal.find('.actions > .ok.button');
     const deleteUrl = $(this).attr('data-url');
 
-    deleteColumnButton.on('click', (e) => {
+    deleteColumnButton.on('click', async (e) => {
       e.preventDefault();
 
-      $.ajax({
-        url: deleteUrl,
-        headers: {
-          'X-Csrf-Token': csrfToken,
-        },
-        contentType: 'application/json',
-        method: 'DELETE',
-      }).done(() => {
+      try {
+        await DELETE(deleteUrl);
+      } catch (error) {
+        console.error(error);
+      } finally {
         window.location.reload();
-      });
+      }
     });
   });
 
@@ -190,7 +182,7 @@ export function initRepoProject() {
     if (!columnTitle.val()) {
       return;
     }
-    const url = $(this).data('url');
+    const url = e.target.getAttribute('data-url');
     createNewColumn(url, columnTitle, projectColorInput);
   });
 }