authorgravatar for maria@kuuro.netmaria <maria@kuuro.net> 2026-09-03 23:08:26-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-03 23:08:26-04:00
log2b10398cca3fa74a7c2187c8d9c23ba789333f5b
tree2863ba1ec33c2236c31824220a0569e99a3b6de2
parentd7884ce90b9845e6e8aa737dfe02062b91b11c91
signature Signed by PGP key B5690EEEBB952194

fix(web): render settings sidebar immediately (#9563)

Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>

2 files changed, 21 insertions(+), 16 deletions(-)

apps/web/src/components/AppSidebarLayout.tsx+2-13
...@@ -1,8 +1,6 @@...@@ -1,8 +1,6 @@
1import { useAtomValue } from "@effect/atom-react";1import { useAtomValue } from "@effect/atom-react";
2import * as Schema from "effect/Schema";2import * as Schema from "effect/Schema";
3import {3import {
4 lazy,
5 Suspense,
6 useEffect,4 useEffect,
7 useState,5 useState,
8 useSyncExternalStore,6 useSyncExternalStore,
...@@ -20,6 +18,7 @@ import { useEnvironmentIdentificationMode, useLegacySidebarEnabled } from "../ho...@@ -20,6 +18,7 @@ import { useEnvironmentIdentificationMode, useLegacySidebarEnabled } from "../ho
20import { usePanelAnimationSettings } from "../panelAnimations";18import { usePanelAnimationSettings } from "../panelAnimations";
21import LegacyThreadSidebar from "./LegacySidebar";19import LegacyThreadSidebar from "./LegacySidebar";
22import ThreadSidebar from "./Sidebar";20import ThreadSidebar from "./Sidebar";
21import { SettingsSidebarNav } from "./settings/SettingsSidebarNav";
23import { SidebarChromeHeader } from "./sidebar/SidebarChrome";22import { SidebarChromeHeader } from "./sidebar/SidebarChrome";
24import {23import {
25 resolveSidebarStageFocusRingOffsetClass,24 resolveSidebarStageFocusRingOffsetClass,
...@@ -45,14 +44,6 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip";...@@ -45,14 +44,6 @@ import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip";
4544
46const MACOS_TRAFFIC_LIGHTS_LEFT_INSET = "90px";45const MACOS_TRAFFIC_LIGHTS_LEFT_INSET = "90px";
4746
48// The settings nav (and the Clerk profile surfaces behind it) only renders on
49// settings routes; lazy-loading it keeps that subtree out of the startup chunk.
50const SettingsSidebarNav = lazy(() =>
51 import("./settings/SettingsSidebarNav").then((module) => ({
52 default: module.SettingsSidebarNav,
53 })),
54);
55
56function subscribeToViewportWidth(onChange: () => void): () => void {47function subscribeToViewportWidth(onChange: () => void): () => void {
57 window.addEventListener("resize", onChange);48 window.addEventListener("resize", onChange);
58 return () => window.removeEventListener("resize", onChange);49 return () => window.removeEventListener("resize", onChange);
...@@ -247,9 +238,7 @@ export function AppSidebarLayout({ children }: { children: ReactNode }) {...@@ -247,9 +238,7 @@ export function AppSidebarLayout({ children }: { children: ReactNode }) {
247 {isOnSettings ? (238 {isOnSettings ? (
248 <>239 <>
249 <SidebarChromeHeader isElectron={isElectron} />240 <SidebarChromeHeader isElectron={isElectron} />
250 <Suspense fallback={null}>241 <SettingsSidebarNav pathname={pathname} />
251 <SettingsSidebarNav pathname={pathname} />
252 </Suspense>
253 </>242 </>
254 ) : legacySidebarEnabled ? (243 ) : legacySidebarEnabled ? (
255 <LegacyThreadSidebar />244 <LegacyThreadSidebar />
apps/web/src/components/settings/SettingsSidebarNav.tsx+19-3
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1import {1import {
2 lazy,
3 Suspense,
2 useCallback,4 useCallback,
3 useEffect,5 useEffect,
4 useMemo,6 useMemo,
...@@ -36,7 +38,6 @@ import {...@@ -36,7 +38,6 @@ import {
36 SidebarMenuSubItem,38 SidebarMenuSubItem,
37 useSidebar,39 useSidebar,
38} from "../ui/sidebar";40} from "../ui/sidebar";
39import { T3ConnectSidebarAvatar, T3ConnectSidebarSignIn } from "../clerk/T3ConnectSidebarSignIn";
40import { SidebarUtilityMenu } from "../sidebar/SidebarChrome";41import { SidebarUtilityMenu } from "../sidebar/SidebarChrome";
41import { scrollToSettingsTarget } from "./settingsLayout";42import { scrollToSettingsTarget } from "./settingsLayout";
42import {43import {
...@@ -47,6 +48,17 @@ import {...@@ -47,6 +48,17 @@ import {
47} from "./settingsSearch";48} from "./settingsSearch";
48import { useAvailableSettingsSearchItems } from "./useAvailableSettingsSearchItems";49import { useAvailableSettingsSearchItems } from "./useAvailableSettingsSearchItems";
4950
51const T3ConnectSidebarSignIn = lazy(() =>
52 import("../clerk/T3ConnectSidebarSignIn").then((module) => ({
53 default: module.T3ConnectSidebarSignIn,
54 })),
55);
56const T3ConnectSidebarAvatar = lazy(() =>
57 import("../clerk/T3ConnectSidebarSignIn").then((module) => ({
58 default: module.T3ConnectSidebarAvatar,
59 })),
60);
61
50const SETTINGS_SECTION_ICONS: Readonly<62const SETTINGS_SECTION_ICONS: Readonly<
51 Record<SettingsPath, ComponentType<{ className?: string }>>63 Record<SettingsPath, ComponentType<{ className?: string }>>
52> = {64> = {
...@@ -370,12 +382,16 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) {...@@ -370,12 +382,16 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) {
370 </SidebarGroup>382 </SidebarGroup>
371 </SidebarContent>383 </SidebarContent>
372 <SidebarFooter className="p-[var(--sidebar-content-inset)]">384 <SidebarFooter className="p-[var(--sidebar-content-inset)]">
373 <T3ConnectSidebarSignIn />385 <Suspense fallback={null}>
386 <T3ConnectSidebarSignIn />
387 </Suspense>
374 <div className="flex items-center gap-1">388 <div className="flex items-center gap-1">
375 <div className="min-w-0 flex-1">389 <div className="min-w-0 flex-1">
376 <SidebarUtilityMenu />390 <SidebarUtilityMenu />
377 </div>391 </div>
378 <T3ConnectSidebarAvatar />392 <Suspense fallback={null}>
393 <T3ConnectSidebarAvatar />
394 </Suspense>
379 </div>395 </div>
380 </SidebarFooter>396 </SidebarFooter>
381 </>397 </>