From 9d815c4dccd550aab18173cdf01116ff2ff3e1ac Mon Sep 17 00:00:00 2001 From: Matt Ciaccio Date: Wed, 22 Apr 2026 02:06:39 +0200 Subject: [PATCH] fix: wrap useSearchParams pages in Suspense for prerender Next.js 15 static prerender bails out when useSearchParams is used outside a Suspense boundary. Extract the hook-using component into an inner child and wrap it in Suspense at the page root. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/app/(auth)/set-password/page.tsx | 22 ++++++++++++++++++---- src/app/(portal)/portal/verify/page.tsx | 18 ++++++++++++++++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/app/(auth)/set-password/page.tsx b/src/app/(auth)/set-password/page.tsx index 2d24f08..d16db42 100644 --- a/src/app/(auth)/set-password/page.tsx +++ b/src/app/(auth)/set-password/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState } from 'react'; +import { Suspense, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; @@ -44,7 +44,7 @@ const requirements: Requirement[] = [ { label: 'Special character', test: (v) => /[^A-Za-z0-9]/.test(v) }, ]; -export default function SetPasswordPage() { +function SetPasswordInner() { const router = useRouter(); const searchParams = useSearchParams(); const token = searchParams.get('token'); @@ -154,8 +154,7 @@ export default function SetPasswordPage() { autoComplete="new-password" disabled={isLoading} className={cn( - errors.confirmPassword && - 'border-destructive focus-visible:ring-destructive', + errors.confirmPassword && 'border-destructive focus-visible:ring-destructive', )} {...register('confirmPassword')} /> @@ -174,3 +173,18 @@ export default function SetPasswordPage() { ); } + +export default function SetPasswordPage() { + return ( + + } + > + + + ); +} diff --git a/src/app/(portal)/portal/verify/page.tsx b/src/app/(portal)/portal/verify/page.tsx index 66630b2..c32d4a9 100644 --- a/src/app/(portal)/portal/verify/page.tsx +++ b/src/app/(portal)/portal/verify/page.tsx @@ -1,10 +1,10 @@ 'use client'; -import { useEffect, useRef } from 'react'; +import { Suspense, useEffect, useRef } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { Loader2 } from 'lucide-react'; -export default function PortalVerifyPage() { +function PortalVerifyInner() { const router = useRouter(); const searchParams = useSearchParams(); const calledRef = useRef(false); @@ -33,3 +33,17 @@ export default function PortalVerifyPage() { ); } + +export default function PortalVerifyPage() { + return ( + + + + } + > + + + ); +}