Skip to content
This repository was archived by the owner on Sep 16, 2026. It is now read-only.

Commit d032f62

Browse files
leoisadev1claude
andauthored
fix(web): wrap useSearchParams in Suspense boundary (#137)
Next.js 15.5 requires useSearchParams() to be wrapped in a Suspense boundary when used in layouts or components that are statically generated. This was causing build failures during pre-rendering of the 404 page. Solution: - Extract PostHog page view tracking into PosthogPageViewTracker component - Wrap PosthogPageViewTracker in <Suspense fallback={null}> - Keep the rest of the Providers component outside Suspense This allows Next.js to pre-render pages without the useSearchParams hook, while still tracking page views on the client side. Fixes build error: useSearchParams() should be wrapped in a suspense boundary at page "/404" Error occurred prerendering page "/_not-found" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent f5381be commit d032f62

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

‎apps/web/src/components/providers.tsx‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useEffect, useMemo, useRef } from "react";
3+
import { Suspense, useEffect, useMemo, useRef } from "react";
44
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
55
import { PostHogProvider } from "posthog-js/react";
66
import { usePathname, useSearchParams } from "next/navigation";
@@ -10,8 +10,7 @@ import { Toaster } from "sonner";
1010
import { initPosthog } from "@/lib/posthog";
1111
import { PosthogBootstrap } from "@/components/posthog-bootstrap";
1212

13-
export default function Providers({ children }: { children: React.ReactNode }) {
14-
const queryClient = useMemo(() => new QueryClient(), []);
13+
function PosthogPageViewTracker() {
1514
const pathname = usePathname();
1615
const searchParams = useSearchParams();
1716
const posthogClient = useMemo(() => initPosthog(), []);
@@ -47,6 +46,13 @@ export default function Providers({ children }: { children: React.ReactNode }) {
4746
previousPathRef.current = `${currentPath || "/"}${search.length > 0 ? `?${search}` : ""}`;
4847
}, [entryReferrer, pathname, posthogClient, searchParams]);
4948

49+
return null;
50+
}
51+
52+
export default function Providers({ children }: { children: React.ReactNode }) {
53+
const queryClient = useMemo(() => new QueryClient(), []);
54+
const posthogClient = useMemo(() => initPosthog(), []);
55+
5056
const appTree = (
5157
<ThemeProvider
5258
attribute="class"
@@ -57,6 +63,9 @@ export default function Providers({ children }: { children: React.ReactNode }) {
5763
<BrandThemeProvider>
5864
<QueryClientProvider client={queryClient}>
5965
<PosthogBootstrap />
66+
<Suspense fallback={null}>
67+
<PosthogPageViewTracker />
68+
</Suspense>
6069
{children}
6170
<Toaster richColors position="bottom-right" />
6271
</QueryClientProvider>

0 commit comments

Comments
 (0)