diff --git a/tools/server/webui/src/lib/constants/settings-config.ts b/tools/server/webui/src/lib/constants/settings-config.ts
index 3764a2856b..8024be92e1 100644
--- a/tools/server/webui/src/lib/constants/settings-config.ts
+++ b/tools/server/webui/src/lib/constants/settings-config.ts
@@ -15,6 +15,8 @@ export const SETTING_CONFIG_DEFAULT: Record =
pdfAsImage: false,
disableAutoScroll: false,
renderUserContentAsMarkdown: false,
+ alwaysShowSidebarOnDesktop: false,
+ autoShowSidebarOnNewChat: true,
autoMicOnEmpty: false,
// make sure these default values are in sync with `common.h`
samplers: 'top_k;typ_p;top_p;min_p;temperature',
@@ -96,6 +98,10 @@ export const SETTING_CONFIG_INFO: Record = {
disableAutoScroll:
'Disable automatic scrolling while messages stream so you can control the viewport position manually.',
renderUserContentAsMarkdown: 'Render user messages using markdown formatting in the chat.',
+ alwaysShowSidebarOnDesktop:
+ 'Always keep the sidebar visible on desktop instead of auto-hiding it.',
+ autoShowSidebarOnNewChat:
+ 'Automatically show sidebar when starting a new chat. Disable to keep the sidebar hidden until you click on it.',
autoMicOnEmpty:
'Automatically show microphone button instead of send button when textarea is empty for models with audio modality support.',
pyInterpreterEnabled:
diff --git a/tools/server/webui/src/routes/+layout.svelte b/tools/server/webui/src/routes/+layout.svelte
index 27dfac19c3..17e13e9f33 100644
--- a/tools/server/webui/src/routes/+layout.svelte
+++ b/tools/server/webui/src/routes/+layout.svelte
@@ -14,6 +14,7 @@
import { goto } from '$app/navigation';
import { modelsStore } from '$lib/stores/models.svelte';
import { TOOLTIP_DELAY_DURATION } from '$lib/constants/tooltip-config';
+ import { IsMobile } from '$lib/hooks/is-mobile.svelte';
let { children } = $props();
@@ -21,6 +22,10 @@
let isHomeRoute = $derived(page.route.id === '/');
let isNewChatMode = $derived(page.url.searchParams.get('new_chat') === 'true');
let showSidebarByDefault = $derived(activeMessages().length > 0 || isLoading());
+ let alwaysShowSidebarOnDesktop = $derived(config().alwaysShowSidebarOnDesktop);
+ let autoShowSidebarOnNewChat = $derived(config().autoShowSidebarOnNewChat);
+ let isMobile = new IsMobile();
+ let isDesktop = $derived(!isMobile.current);
let sidebarOpen = $state(false);
let innerHeight = $state();
let chatSidebar:
@@ -76,6 +81,11 @@
}
$effect(() => {
+ if (alwaysShowSidebarOnDesktop && isDesktop) {
+ sidebarOpen = true;
+ return;
+ }
+
if (isHomeRoute && !isNewChatMode) {
// Auto-collapse sidebar when navigating to home route (but not in new chat mode)
sidebarOpen = false;
@@ -83,8 +93,11 @@
// Keep sidebar open in new chat mode
sidebarOpen = true;
} else if (isChatRoute) {
- // On chat routes, show sidebar by default
- sidebarOpen = true;
+ // On chat routes, only auto-show sidebar if setting is enabled
+ if (autoShowSidebarOnNewChat) {
+ sidebarOpen = true;
+ }
+ // If setting is disabled, don't change sidebar state - let user control it manually
} else {
// Other routes follow default behavior
sidebarOpen = showSidebarByDefault;
@@ -190,12 +203,14 @@
-
+ {#if !(alwaysShowSidebarOnDesktop && isDesktop)}
+
+ {/if}
{@render children?.()}