diff --git a/templates/repo/editor/edit.tmpl b/templates/repo/editor/edit.tmpl
index a6dce81c0..05a8d9668 100644
--- a/templates/repo/editor/edit.tmpl
+++ b/templates/repo/editor/edit.tmpl
@@ -30,7 +30,7 @@
 					<a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.new_file"}}{{else}}{{ctx.Locale.Tr "repo.editor.edit_file"}}{{end}}</a>
 					<a class="item" data-tab="preview" data-url="{{.Repository.Link}}/markup" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL}}" data-markup-mode="file">{{svg "octicon-eye"}} {{ctx.Locale.Tr "preview"}}</a>
 					{{if not .IsNewFile}}
-					<a class="item" data-tab="diff" data-url="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}" data-context="{{.BranchLink}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a>
+					<a class="item" data-tab="diff" hx-params="context,content" hx-vals='{"context":"{{.BranchLink}}"}' hx-include="#edit_area" hx-swap="innerHTML" hx-target=".tab[data-tab='diff']" hx-indicator=".tab[data-tab='diff']" hx-post="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a>
 					{{end}}
 				</div>
 				<div class="ui bottom attached active tab segment" data-tab="write">
@@ -45,7 +45,7 @@
 					{{ctx.Locale.Tr "loading"}}
 				</div>
 				<div class="ui bottom attached tab segment diff edit-diff" data-tab="diff">
-					{{ctx.Locale.Tr "loading"}}
+					<div class="tw-p-16"></div>
 				</div>
 			</div>
 			{{template "repo/editor/commit_form" .}}
diff --git a/web_src/js/features/repo-editor.js b/web_src/js/features/repo-editor.js
index f00f81722..4fe7ed8a4 100644
--- a/web_src/js/features/repo-editor.js
+++ b/web_src/js/features/repo-editor.js
@@ -4,15 +4,14 @@ import {createCodeEditor} from './codeeditor.js';
 import {hideElem, showElem} from '../utils/dom.js';
 import {initMarkupContent} from '../markup/content.js';
 import {attachRefIssueContextPopup} from './contextpopup.js';
-
-const {csrfToken} = window.config;
+import {POST} from '../modules/fetch.js';
 
 function initEditPreviewTab($form) {
   const $tabMenu = $form.find('.tabular.menu');
   $tabMenu.find('.item').tab();
   const $previewTab = $tabMenu.find(`.item[data-tab="${$tabMenu.data('preview')}"]`);
   if ($previewTab.length) {
-    $previewTab.on('click', function () {
+    $previewTab.on('click', async function () {
       const $this = $(this);
       let context = `${$this.data('context')}/`;
       const mode = $this.data('markup-mode') || 'comment';
@@ -21,43 +20,30 @@ function initEditPreviewTab($form) {
         context += treePathEl.val();
       }
       context = context.substring(0, context.lastIndexOf('/'));
-      $.post($this.data('url'), {
-        _csrf: csrfToken,
-        mode,
-        context,
-        text: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val(),
-        file_path: treePathEl.val(),
-      }, (data) => {
+
+      const formData = new FormData();
+      formData.append('mode', mode);
+      formData.append('context', context);
+      formData.append('text', $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val());
+      formData.append('file_path', treePathEl.val());
+      try {
+        const response = await POST($this.data('url'), {data: formData});
+        const data = await response.text();
         const $previewPanel = $form.find(`.tab[data-tab="${$tabMenu.data('preview')}"]`);
         renderPreviewPanelContent($previewPanel, data);
-      });
+      } catch (error) {
+        console.error('Error:', error);
+      }
     });
   }
 }
 
-function initEditDiffTab($form) {
-  const $tabMenu = $form.find('.tabular.menu');
-  $tabMenu.find('.item').tab();
-  $tabMenu.find(`.item[data-tab="${$tabMenu.data('diff')}"]`).on('click', function () {
-    const $this = $(this);
-    $.post($this.data('url'), {
-      _csrf: csrfToken,
-      context: $this.data('context'),
-      content: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val(),
-    }, (data) => {
-      const $diffPreviewPanel = $form.find(`.tab[data-tab="${$tabMenu.data('diff')}"]`);
-      $diffPreviewPanel.html(data);
-    });
-  });
-}
-
 function initEditorForm() {
   if ($('.repository .edit.form').length === 0) {
     return;
   }
 
   initEditPreviewTab($('.repository .edit.form'));
-  initEditDiffTab($('.repository .edit.form'));
 }
 
 function getCursorPosition($e) {