Skip to content

Commit 8897d67

Browse files
committed
fix and update claude rule
1 parent 672ea7f commit 8897d67

File tree

4 files changed

+84
-3
lines changed

4 files changed

+84
-3
lines changed

.claude/rules/react-dashboard.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,38 @@ paths:
5454
- Handle loading and error states appropriately
5555
- Use `try/catch` for async operations
5656

57+
## Next.js App Router
58+
59+
- Pages using `useSearchParams()` MUST be wrapped in a `<Suspense>` boundary for static generation
60+
- Pattern: Create a `{Page}Content` component that uses the hook, wrap it in `<Suspense>` in the default export
61+
- Always provide a loading fallback component
62+
63+
```tsx
64+
// Required pattern for useSearchParams
65+
import { Suspense } from 'react';
66+
import { useSearchParams } from 'next/navigation';
67+
68+
function PageLoading() {
69+
return <div>Loading...</div>;
70+
}
71+
72+
function PageContent() {
73+
const searchParams = useSearchParams();
74+
const param = searchParams.get('param');
75+
// ... component logic
76+
}
77+
78+
export default function Page() {
79+
return (
80+
<Suspense fallback={<PageLoading />}>
81+
<PageContent />
82+
</Suspense>
83+
);
84+
}
85+
```
86+
87+
- See `app/cloud/link/page.tsx` and `app/login/page.tsx` for examples
88+
5789
## Common Patterns
5890

5991
```tsx

.trajectories/active/traj_rsavt0jipi3c.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,30 @@
4343
"reasoning": "Added useSearchParams to read return query param and redirect back after login instead of always going to /app"
4444
},
4545
"significance": "high"
46+
},
47+
{
48+
"ts": 1767860361297,
49+
"type": "decision",
50+
"content": "Added Suspense boundary to login page: Added Suspense boundary to login page",
51+
"raw": {
52+
"question": "Added Suspense boundary to login page",
53+
"chosen": "Added Suspense boundary to login page",
54+
"alternatives": [],
55+
"reasoning": "useSearchParams requires Suspense for Next.js static generation - wrapped LoginContent in Suspense with LoginLoading fallback"
56+
},
57+
"significance": "high"
58+
},
59+
{
60+
"ts": 1767860499290,
61+
"type": "decision",
62+
"content": "Added useSearchParams/Suspense rule to react-dashboard.md: Added useSearchParams/Suspense rule to react-dashboard.md",
63+
"raw": {
64+
"question": "Added useSearchParams/Suspense rule to react-dashboard.md",
65+
"chosen": "Added useSearchParams/Suspense rule to react-dashboard.md",
66+
"alternatives": [],
67+
"reasoning": "Prevents future build failures - useSearchParams requires Suspense boundary for Next.js static generation"
68+
},
69+
"significance": "high"
4670
}
4771
]
4872
}

.trajectories/index.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"version": 1,
3-
"lastUpdated": "2026-01-08T08:05:07.874Z",
3+
"lastUpdated": "2026-01-08T08:21:39.291Z",
44
"trajectories": {
55
"traj_ozd98si6a7ns": {
66
"title": "Fix thinking indicator showing on all messages",

src/dashboard/app/login/page.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,28 @@
88

99
'use client';
1010

11-
import React, { useState, useEffect, useRef } from 'react';
11+
import React, { useState, useEffect, useRef, Suspense } from 'react';
1212
import { useSearchParams } from 'next/navigation';
1313
import Nango from '@nangohq/frontend';
1414
import { LogoIcon } from '../../react-components/Logo';
1515

16-
export default function LoginPage() {
16+
// Loading fallback for Suspense
17+
function LoginLoading() {
18+
return (
19+
<div className="min-h-screen bg-gradient-to-br from-[#0a0a0f] via-[#0d1117] to-[#0a0a0f] flex flex-col items-center justify-center p-4">
20+
<div className="relative z-10 w-full max-w-md">
21+
<div className="flex flex-col items-center mb-8">
22+
<LogoIcon size={48} withGlow={true} />
23+
<h1 className="mt-4 text-2xl font-bold text-white">Agent Relay</h1>
24+
<p className="mt-2 text-text-muted">Loading...</p>
25+
</div>
26+
</div>
27+
</div>
28+
);
29+
}
30+
31+
// Main login content that uses useSearchParams
32+
function LoginContent() {
1733
const searchParams = useSearchParams();
1834
const [isReady, setIsReady] = useState(false);
1935
const [isAuthenticating, setIsAuthenticating] = useState(false);
@@ -253,3 +269,12 @@ export default function LoginPage() {
253269
</div>
254270
);
255271
}
272+
273+
// Export page wrapped in Suspense for static generation
274+
export default function LoginPage() {
275+
return (
276+
<Suspense fallback={<LoginLoading />}>
277+
<LoginContent />
278+
</Suspense>
279+
);
280+
}

0 commit comments

Comments
 (0)