diff --git a/src/lib/i18n/locales/en-GB/translation.json b/src/lib/i18n/locales/en-GB/translation.json
index 4fe6986126..7445bbe4ca 100644
--- a/src/lib/i18n/locales/en-GB/translation.json
+++ b/src/lib/i18n/locales/en-GB/translation.json
@@ -1278,6 +1278,7 @@
"Firecrawl Timeout (s)": "",
"Floating Quick Actions": "",
"Focus Chat Input": "",
+ "Font Family": "",
"Folder": "",
"Folder Background Image": "",
"Folder created successfully": "",
@@ -2903,6 +2904,7 @@
"Use": "",
"Use /v1/chat/completions endpoint instead of /v1/audio/transcriptions for potentially better accuracy.": "",
"Use a Gemini API key for image generation.": "",
+ "Use a local font family for the app interface.": "",
"Use a valid event name or pattern like user.*": "",
"Use a wider chat layout on large displays.": "",
"Use an API key when your ComfyUI server requires one.": "",
diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json
index 6134b8ac3a..92b6b17a20 100644
--- a/src/lib/i18n/locales/en-US/translation.json
+++ b/src/lib/i18n/locales/en-US/translation.json
@@ -1278,6 +1278,7 @@
"Firecrawl Timeout (s)": "",
"Floating Quick Actions": "",
"Focus Chat Input": "",
+ "Font Family": "",
"Folder": "",
"Folder Background Image": "",
"Folder created successfully": "",
@@ -2903,6 +2904,7 @@
"Use": "",
"Use /v1/chat/completions endpoint instead of /v1/audio/transcriptions for potentially better accuracy.": "",
"Use a Gemini API key for image generation.": "",
+ "Use a local font family for the app interface.": "",
"Use a valid event name or pattern like user.*": "",
"Use a wider chat layout on large displays.": "",
"Use an API key when your ComfyUI server requires one.": "",
diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts
index 34f62b7d2c..597372090b 100644
--- a/src/lib/stores/index.ts
+++ b/src/lib/stores/index.ts
@@ -231,6 +231,7 @@ type Settings = {
imageCompression?: boolean;
imageCompressionSize?: any;
textScale?: number;
+ fontFamily?: string | null;
widescreenMode?: null;
largeTextAsFile?: boolean;
promptAutocomplete?: boolean;
diff --git a/src/lib/utils/text-scale.ts b/src/lib/utils/text-scale.ts
index a975c13bf9..5c3876a4dd 100644
--- a/src/lib/utils/text-scale.ts
+++ b/src/lib/utils/text-scale.ts
@@ -1,7 +1,27 @@
-export const setTextScale = (scale) => {
+export const setTextScale = (scale: number) => {
if (typeof document === 'undefined') {
return;
}
document.documentElement.style.setProperty('--app-text-scale', `${scale}`);
};
+
+export const normalizeAppFontFamily = (fontFamily?: string | null) =>
+ typeof fontFamily === 'string' ? fontFamily.trim().replace(/[\u0000-\u001f\u007f]/g, '') : '';
+
+export const setAppFontFamily = (fontFamily?: string | null) => {
+ if (typeof document === 'undefined') {
+ return;
+ }
+
+ const normalized = normalizeAppFontFamily(fontFamily);
+ if (!normalized) {
+ document.documentElement.style.removeProperty('--app-font-family');
+ return;
+ }
+
+ document.documentElement.style.setProperty(
+ '--app-font-family',
+ `"${normalized.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`
+ );
+};
diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte
index b10085df80..633a9f7ec5 100644
--- a/src/routes/(app)/+layout.svelte
+++ b/src/routes/(app)/+layout.svelte
@@ -14,7 +14,7 @@
import { getBanners } from '$lib/apis/configs';
import { getTerminalServers } from '$lib/apis/terminal';
import { getUserSettings } from '$lib/apis/users';
- import { setTextScale } from '$lib/utils/text-scale';
+ import { setAppFontFamily, setTextScale } from '$lib/utils/text-scale';
import { WEBUI_VERSION, WEBUI_API_BASE_URL } from '$lib/constants';
import { compareVersion } from '$lib/utils';
@@ -98,6 +98,7 @@
loadKeybindings(userSettings?.keybindings);
setTextScale($settings?.textScale ?? 1);
+ setAppFontFamily($settings?.fontFamily ?? null);
if (cb) {
await cb();
diff --git a/src/tailwind.css b/src/tailwind.css
index 1526d9c1e8..6c59448417 100644
--- a/src/tailwind.css
+++ b/src/tailwind.css
@@ -36,7 +36,14 @@
}
@layer base {
- html,
+ html {
+ font-family:
+ var(--app-font-family, -apple-system), BlinkMacSystemFont, 'Inter', 'Vazirmatn',
+ ui-sans-serif, system-ui, 'Segoe UI', Roboto, Ubuntu, Cantarell, 'Noto Sans', sans-serif,
+ 'Helvetica Neue', Arial, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
+ 'Noto Color Emoji';
+ }
+
pre {
font-family:
-apple-system, BlinkMacSystemFont, 'Inter', 'Vazirmatn', ui-sans-serif, system-ui, 'Segoe UI',