LibreChat/client/src/App.jsx
Ravi Kumar L 865e1da857
⚙️ refactor: lazy-load React Query Devtools (#13639)
* perf(client): lazy-load query devtools

* fix: keep query devtools deps lazy

* fix: address query devtools review findings

* fix: exclude query devtools from pwa precache

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
2026-06-10 13:06:20 -04:00

94 lines
3.2 KiB
JavaScript

import { useEffect } from 'react';
import { RecoilRoot } from 'recoil';
import { DndProvider } from 'react-dnd';
import { RouterProvider } from 'react-router-dom';
import * as RadixToast from '@radix-ui/react-toast';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { Toast, ThemeProvider, ToastProvider } from '@librechat/client';
import { QueryClient, QueryClientProvider, QueryCache } from '@tanstack/react-query';
import { ScreenshotProvider, useApiErrorBoundary } from './hooks';
import WakeLockManager from '~/components/System/WakeLockManager';
import QueryDevtoolsGate from '~/components/QueryDevtoolsGate';
import LanguageSync from '~/components/System/LanguageSync';
import { getThemeFromEnv } from './utils/getThemeFromEnv';
import { initializeFontSize } from '~/store/fontSize';
import { LiveAnnouncer } from '~/a11y';
import { router } from './routes';
const App = () => {
const { setError } = useApiErrorBoundary();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// Always attempt network requests, even when navigator.onLine is false
// This is needed because localhost is reachable without WiFi
networkMode: 'always',
},
mutations: {
networkMode: 'always',
},
},
queryCache: new QueryCache({
onError: (error) => {
if (error?.response?.status === 401) {
setError(error);
}
},
}),
});
useEffect(() => {
initializeFontSize();
}, []);
// Load theme from environment variables if available
const envTheme = getThemeFromEnv();
return (
<QueryClientProvider client={queryClient}>
<RecoilRoot>
<LanguageSync />
<LiveAnnouncer>
<ThemeProvider
// Only pass initialTheme and themeRGB if environment theme exists
// This allows localStorage values to persist when no env theme is set
{...(envTheme && { initialTheme: 'system', themeRGB: envTheme })}
>
{/* The ThemeProvider will automatically:
1. Apply dark/light mode classes
2. Apply custom theme colors if envTheme is provided
3. Otherwise use stored theme preferences from localStorage
4. Fall back to default theme colors if nothing is stored */}
<RadixToast.Provider>
<ToastProvider>
<DndProvider backend={HTML5Backend}>
<RouterProvider router={router} />
<WakeLockManager />
<QueryDevtoolsGate />
<Toast />
<RadixToast.Viewport className="pointer-events-none fixed inset-0 z-[1000] mx-auto my-2 flex max-w-[560px] flex-col items-stretch justify-start md:pb-5" />
</DndProvider>
</ToastProvider>
</RadixToast.Provider>
</ThemeProvider>
</LiveAnnouncer>
</RecoilRoot>
</QueryClientProvider>
);
};
export default () => (
<ScreenshotProvider>
<App />
<iframe
src="assets/silence.mp3"
allow="autoplay"
id="audio"
title="audio-silence"
style={{
display: 'none',
}}
/>
</ScreenshotProvider>
);