diff --git a/frontend/src/components/ChatBubble/index.jsx b/frontend/src/components/ChatBubble/index.jsx
index 4ffc3d085ea3c97d4efc9cb401b16f8b3a83e351..7b37cd5d17e540e43e65b134a7d3958fa2a8b95c 100644
--- a/frontend/src/components/ChatBubble/index.jsx
+++ b/frontend/src/components/ChatBubble/index.jsx
@@ -1,6 +1,8 @@
 import React from "react";
 import UserIcon from "../UserIcon";
 import { userFromStorage } from "@/utils/request";
+import renderMarkdown from "@/utils/chat/markdown";
+import DOMPurify from "@/utils/chat/purify";
 
 export default function ChatBubble({ message, type, popMsg }) {
   const isUser = type === "user";
@@ -16,11 +18,12 @@ export default function ChatBubble({ message, type, popMsg }) {
             role={type}
           />
 
-          <span
-            className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
-          >
-            {message}
-          </span>
+          <div
+            className={`markdown whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
+            dangerouslySetInnerHTML={{
+              __html: DOMPurify.sanitize(renderMarkdown(message)),
+            }}
+          />
         </div>
       </div>
     </div>
diff --git a/frontend/src/components/EditingChatBubble/index.jsx b/frontend/src/components/EditingChatBubble/index.jsx
index feabd4c6ee174b7daa163a5c23ec86dfbcb2dba1..652297c7914f40582d377bd79f286620a6a0448c 100644
--- a/frontend/src/components/EditingChatBubble/index.jsx
+++ b/frontend/src/components/EditingChatBubble/index.jsx
@@ -1,6 +1,8 @@
 import React, { useState } from "react";
 import { X } from "@phosphor-icons/react";
 import { useTranslation } from "react-i18next";
+import renderMarkdown from "@/utils/chat/markdown";
+import DOMPurify from "@/utils/chat/purify";
 
 export default function EditingChatBubble({
   message,
@@ -57,9 +59,12 @@ export default function EditingChatBubble({
             />
           ) : (
             tempMessage && (
-              <p className=" font-[500] md:font-semibold text-sm md:text-base break-words light:invert">
-                {tempMessage}
-              </p>
+              <div
+                className="markdown font-[500] md:font-semibold text-sm md:text-base break-words light:invert"
+                dangerouslySetInnerHTML={{
+                  __html: DOMPurify.sanitize(renderMarkdown(tempMessage)),
+                }}
+              />
             )
           )}
         </div>
diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx
index a5d60db4e077b3c2c13595d49be60522d1ee3933..5a5454bb283f153bb35d1cf5451a9d2afe8dd2e8 100644
--- a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx
+++ b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx
@@ -6,7 +6,7 @@ import renderMarkdown from "@/utils/chat/markdown";
 import { userFromStorage } from "@/utils/request";
 import Citations from "../Citation";
 import { v4 } from "uuid";
-import createDOMPurify from "dompurify";
+import DOMPurify from "@/utils/chat/purify";
 import { EditMessageForm, useEditMessage } from "./Actions/EditMessage";
 import { useWatchDeleteMessage } from "./Actions/DeleteMessage";
 import TTSMessage from "./Actions/TTSButton";
@@ -17,11 +17,6 @@ import {
   ThoughtChainComponent,
 } from "../ThoughtContainer";
 
-const DOMPurify = createDOMPurify(window);
-DOMPurify.setConfig({
-  ADD_ATTR: ["target", "rel"],
-});
-
 const HistoricalMessage = ({
   uuid = v4(),
   message,
diff --git a/frontend/src/utils/chat/purify.js b/frontend/src/utils/chat/purify.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6cf85206602c4153ff4c117c3177f4764ff8053
--- /dev/null
+++ b/frontend/src/utils/chat/purify.js
@@ -0,0 +1,8 @@
+import createDOMPurify from "dompurify";
+
+const DOMPurify = createDOMPurify(window);
+DOMPurify.setConfig({
+  ADD_ATTR: ["target", "rel"],
+});
+
+export default DOMPurify;