Skip to content

Feat: next headless example#171

Open
rtomas wants to merge 3 commits intomainfrom
feat/next-headless-example
Open

Feat: next headless example#171
rtomas wants to merge 3 commits intomainfrom
feat/next-headless-example

Conversation

@rtomas
Copy link
Contributor

@rtomas rtomas commented Jan 21, 2026

Create a new headless example for Next.js

@vercel
Copy link

vercel bot commented Jan 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
appkit-pay Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-javascript-bitcoin Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-javascript-ethers Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-javascript-solana Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-javascript-wagmi Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-next-bitcoin Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-next-ethers Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-next-multichain Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-next-solana Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-next-wagmi Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-react-bitcoin Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-react-core-up Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-react-ethers Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-react-ethers5 Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-react-multichain Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-react-solana Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-react-wagmi Building Building Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-vue-bitcoin Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-vue-ethers Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-vue-multichain Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-vue-solana Ready Ready Preview, Comment Jan 21, 2026 7:54pm
appkit-web-examples-vue-wagmi Ready Ready Preview, Comment Jan 21, 2026 7:54pm
react-core-universal-connector Ready Ready Preview, Comment Jan 21, 2026 7:54pm

Request Review

@claude
Copy link

claude bot commented Jan 21, 2026

Claude finished @rtomas's task in 1m 47s —— View job


Code Review: Next.js Headless Example

Found 5 issue(s)

Issue 1: Missing useEffect dependency causes exhaustive-deps warning

ID: allwallets-useeffect-deps-a3f2
File: nextjs/next-appkit-headless/src/components/AllWalletsView.tsx:63
Severity: MEDIUM
Category: code_quality

Context:

  • Pattern: useEffect at line 50-63 has empty dependency array but references fetchWallets function
  • Risk: Effect won't re-run if fetchWallets reference changes, potentially causing stale closures
  • Impact: Could lead to runtime errors or unexpected behavior if function reference updates
  • Trigger: When component remounts or fetchWallets reference changes

Recommendation: Add fetchWallets to dependency array:

useEffect(() => {
  const loadWallets = async () => {
    try {
      setFetchError(null)
      await fetchWallets?.()
    } catch (err) {
      setFetchError('Failed to load wallets')
      console.error('Wallet fetch error:', err)
    }
  }
  loadWallets()
}, [fetchWallets])

Issue 2: Missing cleanup for debounce timer

ID: allwallets-debounce-cleanup-b7c4
File: nextjs/next-appkit-headless/src/components/AllWalletsView.tsx:29
Severity: LOW
Category: code_quality

Context:

  • Pattern: Debounce timer set at line 35 but no cleanup when component unmounts
  • Risk: Memory leak if component unmounts while timer is pending
  • Impact: setTimeout callback could run on unmounted component, attempting state updates
  • Trigger: User navigates away from AllWalletsView before 500ms debounce completes

Recommendation: Add cleanup in useEffect:

useEffect(() => {
  return () => {
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current)
    }
  }
}, [])

Issue 3: Missing error handling for async wallet connection

ID: actionbuttons-signmsg-error-d9e1
File: nextjs/next-appkit-headless/src/components/ActionButtonList.tsx:53
Severity: MEDIUM
Category: code_quality

Context:

  • Pattern: handleSignMsg at line 53 is async but lacks try-catch block
  • Risk: Unhandled promise rejection if signMessageAsync fails (user rejects, network error)
  • Impact: Uncaught errors show in console, poor UX with no user feedback on failure
  • Trigger: User rejects signature request in wallet or network issues occur

Recommendation: Add error handling:

const handleSignMsg = async () => {
  try {
    const msg = "Hello Reown AppKit!"
    const sig = await signMessageAsync({ message: msg, account: address as Address })
    sendSignMsg(sig)
  } catch (err) {
    console.error('Error signing message:', err)
    // Optionally show user-facing error message
  }
}

Issue 4: Same issues in React example

ID: react-same-issues-f2a8
File: react/react-wagmi-headless/src/components/AllWalletsView.tsx:61
Severity: MEDIUM
Category: code_quality

Context:

Recommendation: Apply same fixes as Issues #1 and #2 to React example

Issue 5: Clipboard API without error handling

ID: qrdialog-clipboard-error-c5d3
File: nextjs/next-appkit-headless/src/components/WalletConnectQRDialog.tsx:47
Severity: LOW
Category: code_quality

Context:

  • Pattern: navigator.clipboard.writeText() at line 47 can fail (permissions, HTTPS required, browser support)
  • Risk: Silent failure in browsers without clipboard support or when user denies permission
  • Impact: User clicks "Copy" but nothing happens, no feedback on success/failure
  • Trigger: Non-HTTPS context, denied permissions, unsupported browsers

Recommendation: Add error handling and user feedback:

onClick={async () => {
  try {
    await navigator.clipboard.writeText(wcUri)
    // Show success toast/message
  } catch (err) {
    console.error('Failed to copy:', err)
    // Fallback: select text or show error message
  }
}}

Summary

Solid implementation following AppKit patterns. Config properly uses ssr: true for Next.js, createAppKit called at module level, networks imported correctly. Main issues: missing useEffect dependencies, lack of error handling in async operations, and missing cleanup for timers. No security vulnerabilities found.

✅ CLAUDE.md compliance: Networks from @reown/appkit/networks, typed network array, env variables used, all Reown packages at 1.8.16


}
}
loadWallets()
}, [])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Auto Review Issue: Missing useEffect dependency causes exhaustive-deps warning

Severity: MEDIUM
Category: code_quality
Tool: Claude Auto Review

Context:

  • Pattern: useEffect at line 50-63 has empty dependency array but references fetchWallets function
  • Risk: Effect won't re-run if fetchWallets reference changes, potentially causing stale closures
  • Impact: Could lead to runtime errors or unexpected behavior if function reference updates
  • Trigger: When component remounts or fetchWallets reference changes

Recommendation: Add fetchWallets to dependency array:

useEffect(() => {
  const loadWallets = async () => {
    try {
      setFetchError(null)
      await fetchWallets?.()
    } catch (err) {
      setFetchError('Failed to load wallets')
      console.error('Wallet fetch error:', err)
    }
  }
  loadWallets()
}, [fetchWallets])

const [fetchError, setFetchError] = useState<string | null>(null)

const [searchQuery, setSearchQuery] = useState('')
const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Auto Review Issue: Missing cleanup for debounce timer

Severity: LOW
Category: code_quality
Tool: Claude Auto Review

Context:

  • Pattern: Debounce timer set at line 35 but no cleanup when component unmounts
  • Risk: Memory leak if component unmounts while timer is pending
  • Impact: setTimeout callback could run on unmounted component, attempting state updates
  • Trigger: User navigates away from AllWalletsView before 500ms debounce completes

Recommendation: Add cleanup in useEffect:

useEffect(() => {
  return () => {
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current)
    }
  }
}, [])

}

// function to sign a msg
const handleSignMsg = async () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Auto Review Issue: Missing error handling for async wallet connection

Severity: MEDIUM
Category: code_quality
Tool: Claude Auto Review

Context:

  • Pattern: handleSignMsg at line 53 is async but lacks try-catch block
  • Risk: Unhandled promise rejection if signMessageAsync fails (user rejects, network error)
  • Impact: Uncaught errors show in console, poor UX with no user feedback on failure
  • Trigger: User rejects signature request in wallet or network issues occur

Recommendation: Add error handling:

const handleSignMsg = async () => {
  try {
    const msg = "Hello Reown AppKit!"
    const sig = await signMessageAsync({ message: msg, account: address as Address })
    sendSignMsg(sig)
  } catch (err) {
    console.error('Error signing message:', err)
    // Optionally show user-facing error message
  }
}

}
}
loadWallets()
}, [])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Auto Review Issue: Same issues in React example

Severity: MEDIUM
Category: code_quality
Tool: Claude Auto Review

Context:

Recommendation: Apply same fixes as Issues #1 and #2 to React example

/>
<button
className="copy-button"
onClick={() => navigator.clipboard.writeText(wcUri)}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Auto Review Issue: Clipboard API without error handling

Severity: LOW
Category: code_quality
Tool: Claude Auto Review

Context:

  • Pattern: navigator.clipboard.writeText() at line 47 can fail (permissions, HTTPS required, browser support)
  • Risk: Silent failure in browsers without clipboard support or when user denies permission
  • Impact: User clicks "Copy" but nothing happens, no feedback on success/failure
  • Trigger: Non-HTTPS context, denied permissions, unsupported browsers

Recommendation: Add error handling and user feedback:

onClick={async () => {
  try {
    await navigator.clipboard.writeText(wcUri)
    // Show success toast/message
  } catch (err) {
    console.error('Failed to copy:', err)
    // Fallback: select text or show error message
  }
}}

Summary

Solid implementation following AppKit patterns. Config properly uses ssr: true for Next.js, createAppKit called at module level, networks imported correctly. Main issues: missing useEffect dependencies, lack of error handling in async operations, and missing cleanup for timers. No security vulnerabilities found.

✅ CLAUDE.md compliance: Networks from @reown/appkit/networks, typed network array, env variables used, all Reown packages at 1.8.16


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant