diff --git a/frontend/src/locales/ar/common.js b/frontend/src/locales/ar/common.js index cc85ea8d77b..a4ab12253b8 100644 --- a/frontend/src/locales/ar/common.js +++ b/frontend/src/locales/ar/common.js @@ -804,6 +804,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/da/common.js b/frontend/src/locales/da/common.js index 51089ea38b2..9c63f2aabaa 100644 --- a/frontend/src/locales/da/common.js +++ b/frontend/src/locales/da/common.js @@ -843,6 +843,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/de/common.js b/frontend/src/locales/de/common.js index 4106d401cbe..152198e7909 100644 --- a/frontend/src/locales/de/common.js +++ b/frontend/src/locales/de/common.js @@ -546,6 +546,10 @@ const TRANSLATIONS = { icon: "Icon", link: "Link", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/en/common.js b/frontend/src/locales/en/common.js index b05399c32a6..3d5c5f6dec0 100644 --- a/frontend/src/locales/en/common.js +++ b/frontend/src/locales/en/common.js @@ -564,6 +564,11 @@ const TRANSLATIONS = { icon: "Icon", link: "Link", }, + "render-html": { + title: "Render HTML in chat", + description: + "Render HTML responses in assistant responses.\nThis can result in a much higher fidelity of response quality, but can also lead to potential security risks.", + }, }, }, diff --git a/frontend/src/locales/es/common.js b/frontend/src/locales/es/common.js index 3d7e830be6b..eeed8283376 100644 --- a/frontend/src/locales/es/common.js +++ b/frontend/src/locales/es/common.js @@ -557,6 +557,10 @@ const TRANSLATIONS = { icon: "Icono", link: "Enlace", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/et/common.js b/frontend/src/locales/et/common.js index c6d04c4631d..f4a177ea412 100644 --- a/frontend/src/locales/et/common.js +++ b/frontend/src/locales/et/common.js @@ -523,6 +523,10 @@ const TRANSLATIONS = { icon: "Ikoon", link: "Link", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/fa/common.js b/frontend/src/locales/fa/common.js index 1f0cd82647b..67bc042b9d0 100644 --- a/frontend/src/locales/fa/common.js +++ b/frontend/src/locales/fa/common.js @@ -796,6 +796,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/fr/common.js b/frontend/src/locales/fr/common.js index f12183466f3..a2ed242b9ce 100644 --- a/frontend/src/locales/fr/common.js +++ b/frontend/src/locales/fr/common.js @@ -804,6 +804,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/he/common.js b/frontend/src/locales/he/common.js index 84ffe023fa9..e572d10d023 100644 --- a/frontend/src/locales/he/common.js +++ b/frontend/src/locales/he/common.js @@ -529,6 +529,10 @@ const TRANSLATIONS = { icon: "סמל", link: "קישור", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/it/common.js b/frontend/src/locales/it/common.js index 442a5f2c7ad..7d2470a71a6 100644 --- a/frontend/src/locales/it/common.js +++ b/frontend/src/locales/it/common.js @@ -802,6 +802,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/ja/common.js b/frontend/src/locales/ja/common.js index 45e47e4d0bd..e75590aa7d3 100644 --- a/frontend/src/locales/ja/common.js +++ b/frontend/src/locales/ja/common.js @@ -835,6 +835,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/ko/common.js b/frontend/src/locales/ko/common.js index 28fd58d4e4a..f4dcc540965 100644 --- a/frontend/src/locales/ko/common.js +++ b/frontend/src/locales/ko/common.js @@ -532,6 +532,10 @@ const TRANSLATIONS = { icon: "아이콘", link: "링크", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/lv/common.js b/frontend/src/locales/lv/common.js index 9786bce5c1c..76c4a104798 100644 --- a/frontend/src/locales/lv/common.js +++ b/frontend/src/locales/lv/common.js @@ -541,6 +541,10 @@ const TRANSLATIONS = { icon: "Ikona", link: "Saite", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/nl/common.js b/frontend/src/locales/nl/common.js index 3d300d0af24..61bcc7e016a 100644 --- a/frontend/src/locales/nl/common.js +++ b/frontend/src/locales/nl/common.js @@ -799,6 +799,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/pl/common.js b/frontend/src/locales/pl/common.js index d7673520a14..a97c9da5463 100644 --- a/frontend/src/locales/pl/common.js +++ b/frontend/src/locales/pl/common.js @@ -546,6 +546,10 @@ const TRANSLATIONS = { icon: "Ikona", link: "Link", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/pt_BR/common.js b/frontend/src/locales/pt_BR/common.js index 7795a3e98d4..ef19a448495 100644 --- a/frontend/src/locales/pt_BR/common.js +++ b/frontend/src/locales/pt_BR/common.js @@ -531,6 +531,10 @@ const TRANSLATIONS = { icon: "Ícone", link: "Link", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/ro/common.js b/frontend/src/locales/ro/common.js index 35556747d4b..d30857e41f3 100644 --- a/frontend/src/locales/ro/common.js +++ b/frontend/src/locales/ro/common.js @@ -998,6 +998,10 @@ const TRANSLATIONS = { icon: "Iconiță", link: "Link", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/ru/common.js b/frontend/src/locales/ru/common.js index aebe5b68a98..9e9eeb94456 100644 --- a/frontend/src/locales/ru/common.js +++ b/frontend/src/locales/ru/common.js @@ -844,6 +844,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/tr/common.js b/frontend/src/locales/tr/common.js index cadf6f929c4..13206e48299 100644 --- a/frontend/src/locales/tr/common.js +++ b/frontend/src/locales/tr/common.js @@ -799,6 +799,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/vn/common.js b/frontend/src/locales/vn/common.js index 6b095cd7814..43b3037acce 100644 --- a/frontend/src/locales/vn/common.js +++ b/frontend/src/locales/vn/common.js @@ -798,6 +798,10 @@ const TRANSLATIONS = { icon: null, link: null, }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/locales/zh/common.js b/frontend/src/locales/zh/common.js index 95872cd59f7..35f438c2418 100644 --- a/frontend/src/locales/zh/common.js +++ b/frontend/src/locales/zh/common.js @@ -509,6 +509,10 @@ const TRANSLATIONS = { icon: "图标", link: "链接", }, + "render-html": { + title: null, + description: null, + }, }, }, api: { diff --git a/frontend/src/locales/zh_TW/common.js b/frontend/src/locales/zh_TW/common.js index f3acd752cec..30a0a431654 100644 --- a/frontend/src/locales/zh_TW/common.js +++ b/frontend/src/locales/zh_TW/common.js @@ -806,6 +806,10 @@ const TRANSLATIONS = { icon: "圖示", link: "連結", }, + "render-html": { + title: null, + description: null, + }, }, }, "main-page": { diff --git a/frontend/src/models/appearance.js b/frontend/src/models/appearance.js index e1e45b454ea..fce05c57387 100644 --- a/frontend/src/models/appearance.js +++ b/frontend/src/models/appearance.js @@ -4,7 +4,8 @@ import { APPEARANCE_SETTINGS } from "@/utils/constants"; * @typedef { 'showScrollbar' | * 'autoSubmitSttInput' | * 'autoPlayAssistantTtsResponse' | - * 'enableSpellCheck' + * 'enableSpellCheck' | + * 'renderHTML' * } AvailableSettings - The supported settings for the appearance model. */ @@ -14,11 +15,12 @@ const Appearance = { autoSubmitSttInput: true, autoPlayAssistantTtsResponse: false, enableSpellCheck: true, + renderHTML: false, }, /** * Fetches any locally storage settings for the user - * @returns {{showScrollbar: boolean}} + * @returns {{showScrollbar: boolean, autoSubmitSttInput: boolean, autoPlayAssistantTtsResponse: boolean, enableSpellCheck: boolean, renderHTML: boolean}} */ getSettings: () => { try { diff --git a/frontend/src/pages/GeneralSettings/Settings/Chat/index.jsx b/frontend/src/pages/GeneralSettings/Settings/Chat/index.jsx index bd32e4ff8bf..676086642b5 100644 --- a/frontend/src/pages/GeneralSettings/Settings/Chat/index.jsx +++ b/frontend/src/pages/GeneralSettings/Settings/Chat/index.jsx @@ -5,6 +5,7 @@ import AutoSubmit from "../components/AutoSubmit"; import AutoSpeak from "../components/AutoSpeak"; import SpellCheck from "../components/SpellCheck"; import ShowScrollbar from "../components/ShowScrollbar"; +import ChatRenderHTML from "../components/ChatRenderHTML"; export default function ChatSettings() { const { t } = useTranslation(); @@ -31,6 +32,7 @@ export default function ChatSettings() { + diff --git a/frontend/src/pages/GeneralSettings/Settings/components/ChatRenderHTML/index.jsx b/frontend/src/pages/GeneralSettings/Settings/components/ChatRenderHTML/index.jsx new file mode 100644 index 00000000000..70109405f9c --- /dev/null +++ b/frontend/src/pages/GeneralSettings/Settings/components/ChatRenderHTML/index.jsx @@ -0,0 +1,56 @@ +import React, { useState, useEffect } from "react"; +import Appearance from "@/models/appearance"; +import { useTranslation } from "react-i18next"; + +export default function ChatRenderHTML() { + const { t } = useTranslation(); + const [saving, setSaving] = useState(false); + const [renderHTML, setRenderHTML] = useState(false); + + const handleChange = async (e) => { + const newValue = e.target.checked; + setRenderHTML(newValue); + setSaving(true); + try { + Appearance.updateSettings({ renderHTML: newValue }); + } catch (error) { + console.error("Failed to update appearance settings:", error); + setRenderHTML(!newValue); + } + setSaving(false); + }; + + useEffect(() => { + function fetchSettings() { + const settings = Appearance.getSettings(); + setRenderHTML(settings.renderHTML); + } + fetchSettings(); + }, []); + + return ( +
+

+ {t("customization.items.render-html.title")} +

+

+ {t("customization.items.render-html.description")} +

+
+ +
+
+ ); +} diff --git a/frontend/src/utils/chat/markdown.js b/frontend/src/utils/chat/markdown.js index 015d66ab1d3..27e077a5206 100644 --- a/frontend/src/utils/chat/markdown.js +++ b/frontend/src/utils/chat/markdown.js @@ -1,13 +1,14 @@ import { encode as HTMLEncode } from "he"; import markdownIt from "markdown-it"; import markdownItKatexPlugin from "./plugins/markdown-katex"; +import Appearance from "@/models/appearance"; import hljs from "highlight.js"; import "./themes/github-dark.css"; import "./themes/github.css"; import { v4 } from "uuid"; const markdown = markdownIt({ - html: false, + html: Appearance.get("renderHTML") ?? false, typographer: true, highlight: function (code, lang) { const uuid = v4();