diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 852204b25..d2aec8242 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { Suspense } from 'react';
import { RainbowThemeProvider } from './components/shared/RainbowThemeProvider';
import { FileContextProvider } from './contexts/FileContext';
import { FilesModalProvider } from './contexts/FilesModalContext';
@@ -8,14 +8,30 @@ import HomePage from './pages/HomePage';
import './styles/tailwind.css';
import './index.css';
+// Loading component for i18next suspense
+const LoadingFallback = () => (
+
+ Loading...
+
+);
+
export default function App() {
return (
-
-
-
-
-
-
-
+ }>
+
+
+
+
+
+
+
+
);
}
diff --git a/frontend/src/hooks/useToolManagement.tsx b/frontend/src/hooks/useToolManagement.tsx
index 3e50202a4..be0720169 100644
--- a/frontend/src/hooks/useToolManagement.tsx
+++ b/frontend/src/hooks/useToolManagement.tsx
@@ -118,7 +118,7 @@ interface ToolManagementResult {
}
export const useToolManagement = (): ToolManagementResult => {
- const { t, ready } = useTranslation();
+ const { t } = useTranslation();
const [selectedToolKey, setSelectedToolKey] = useState(null);
const [toolSelectedFileIds, setToolSelectedFileIds] = useState([]);
@@ -136,10 +136,6 @@ export const useToolManagement = (): ToolManagementResult => {
}, [endpointsLoading, endpointStatus]);
const toolRegistry: ToolRegistry = useMemo(() => {
- if (!ready) {
- return {};
- }
-
const availableTools: ToolRegistry = {};
Object.keys(toolDefinitions).forEach(toolKey => {
if (isToolAvailable(toolKey)) {
@@ -151,7 +147,7 @@ export const useToolManagement = (): ToolManagementResult => {
}
});
return availableTools;
- }, [t, isToolAvailable, ready]);
+ }, [t, isToolAvailable]);
useEffect(() => {
if (!endpointsLoading && selectedToolKey && !toolRegistry[selectedToolKey]) {
diff --git a/frontend/src/i18n.ts b/frontend/src/i18n.ts
index c8d7c4798..fd778639d 100644
--- a/frontend/src/i18n.ts
+++ b/frontend/src/i18n.ts
@@ -61,6 +61,9 @@ i18n
nonExplicitSupportedLngs: false,
debug: process.env.NODE_ENV === 'development',
+ // Ensure synchronous loading to prevent timing issues
+ initImmediate: false,
+
interpolation: {
escapeValue: false, // React already escapes values
},
@@ -75,16 +78,15 @@ i18n
},
react: {
- useSuspense: false, // Set to false to avoid suspense issues with SSR
+ useSuspense: true, // Enable suspense to prevent premature rendering
+ bindI18n: 'languageChanged loaded',
+ bindI18nStore: 'added removed',
+ transEmptyNodeValue: '', // Return empty string for missing keys instead of key name
+ transSupportBasicHtmlNodes: true,
+ transKeepBasicHtmlNodesFor: ['br', 'strong', 'i', 'p'],
},
});
-// Map base language codes to specific locales
-i18n.services.languageUtils.formatLanguageCode = (lng) => {
- if (lng === 'en') return 'en-GB';
- return lng;
-};
-
// Set document direction based on language
i18n.on('languageChanged', (lng) => {
const isRTL = rtlLanguages.includes(lng);