fix: move OnboardingProvider inside BrowserRouter to fix useLocation error
Some checks failed
CI/CD - Build & Test / Backend Tests (push) Has been cancelled
CI/CD - Build & Test / Frontend Tests (push) Has been cancelled
CI/CD - Build & Test / Security Scans (push) Has been cancelled
CI/CD - Build & Test / Docker Build Test (push) Has been cancelled
CI/CD - Build & Test / Terraform Validate (push) Has been cancelled
Deploy to Production / Build & Test (push) Has been cancelled
Deploy to Production / Security Scan (push) Has been cancelled
Deploy to Production / Build Docker Images (push) Has been cancelled
Deploy to Production / Deploy to Staging (push) Has been cancelled
Deploy to Production / E2E Tests (push) Has been cancelled
Deploy to Production / Deploy to Production (push) Has been cancelled
E2E Tests / Run E2E Tests (push) Has been cancelled
E2E Tests / Visual Regression Tests (push) Has been cancelled
E2E Tests / Smoke Tests (push) Has been cancelled

The OnboardingProvider component uses useLocation() from react-router,
but it was placed outside the BrowserRouter in the component tree.
This caused the error:
'useLocation() may be used only in the context of a <Router> component.'

Fixed by:
1. Creating a new RouterProviders wrapper component inside BrowserRouter
2. Moving OnboardingProvider, KeyboardShortcutsProvider, and CommandPalette
   inside the RouterProviders (which is inside BrowserRouter)
3. Keeping other providers (I18nProvider, ThemeProvider, QueryProvider, AuthProvider)
   outside BrowserRouter as they don't need router context

This ensures all components that use router hooks are properly wrapped
in the Router context.

Frontend now renders correctly without JavaScript errors.
This commit is contained in:
Luca Sacchi Ricciardi
2026-04-07 23:54:58 +02:00
parent a1068ad99b
commit 26037cf511

View File

@@ -33,19 +33,14 @@ function ProtectedLayout() {
); );
} }
// Wrapper for routes with providers // Wrapper for routes with providers (outside Router)
function AppProviders({ children }: { children: React.ReactNode }) { function AppProviders({ children }: { children: React.ReactNode }) {
return ( return (
<I18nProvider> <I18nProvider>
<ThemeProvider defaultTheme="system"> <ThemeProvider defaultTheme="system">
<QueryProvider> <QueryProvider>
<AuthProvider> <AuthProvider>
<OnboardingProvider> {children}
<KeyboardShortcutsProvider>
{children}
<CommandPalette />
</KeyboardShortcutsProvider>
</OnboardingProvider>
</AuthProvider> </AuthProvider>
</QueryProvider> </QueryProvider>
</ThemeProvider> </ThemeProvider>
@@ -53,33 +48,47 @@ function AppProviders({ children }: { children: React.ReactNode }) {
); );
} }
// Wrapper for providers that need Router context
function RouterProviders({ children }: { children: React.ReactNode }) {
return (
<OnboardingProvider>
<KeyboardShortcutsProvider>
{children}
<CommandPalette />
</KeyboardShortcutsProvider>
</OnboardingProvider>
);
}
function App() { function App() {
return ( return (
<AppProviders> <AppProviders>
<BrowserRouter> <BrowserRouter>
<Suspense fallback={<PageLoader />}> <RouterProviders>
<Routes> <Suspense fallback={<PageLoader />}>
{/* Public routes */} <Routes>
<Route path="/login" element={<Login />} /> {/* Public routes */}
<Route path="/register" element={<Register />} /> <Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
{/* Protected routes with layout */} {/* Protected routes with layout */}
<Route path="/" element={<ProtectedLayout />}> <Route path="/" element={<ProtectedLayout />}>
<Route index element={<Dashboard />} /> <Route index element={<Dashboard />} />
<Route path="scenarios" element={<ScenariosPage />} /> <Route path="scenarios" element={<ScenariosPage />} />
<Route path="scenarios/:id" element={<ScenarioDetail />} /> <Route path="scenarios/:id" element={<ScenarioDetail />} />
<Route path="scenarios/:id/reports" element={<Reports />} /> <Route path="scenarios/:id/reports" element={<Reports />} />
<Route path="compare" element={<Compare />} /> <Route path="compare" element={<Compare />} />
<Route path="settings/api-keys" element={<ApiKeys />} /> <Route path="settings/api-keys" element={<ApiKeys />} />
<Route path="analytics" element={<AnalyticsDashboard />} /> <Route path="analytics" element={<AnalyticsDashboard />} />
</Route> </Route>
{/* 404 */} {/* 404 */}
<Route path="*" element={<NotFound />} /> <Route path="*" element={<NotFound />} />
</Routes> </Routes>
</Suspense> </Suspense>
</RouterProviders>
<Toaster />
</BrowserRouter> </BrowserRouter>
<Toaster />
</AppProviders> </AppProviders>
); );
} }