30 Common Mistakes Web3 Frontend Developers Make (And How to Avoid Them)
Web3 frontend development has unique challenges around wallet connections, transaction handling, and blockchain state. Here are the mistakes that trip up most developers.
Wallet Connection Issues
Assuming wallet is always connected
highNot handling disconnected state leads to crashes and poor UX.
Fix: Always check connection state. Show appropriate UI for each state.
Not handling chain switching
highUsers switching networks in wallet breaks app if not handled.
Fix: Listen for chain changes. Prompt users to switch back or adapt UI.
Only supporting one wallet
mediumMetaMask-only apps exclude mobile users and hardware wallet users.
Fix: Use RainbowKit or Web3Modal to support multiple wallets.
Not persisting connection state
mediumUsers have to reconnect wallet on every page refresh.
Fix: Use wagmi's auto-connect feature. Store connection preference.
Blocking UI during wallet prompts
mediumUser cannot do anything while waiting for wallet signature.
Fix: Show loading state but allow cancellation. Timeout long requests.
Transaction Handling
Not showing transaction status
highUsers don't know if transaction succeeded, failed, or is pending.
Fix: Show clear pending, success, and error states. Link to explorer.
No gas estimation before send
mediumTransactions fail due to insufficient gas without warning.
Fix: Simulate transactions before sending. Show estimated gas cost.
Ignoring transaction reverts
highSilent failures leave users confused about what happened.
Fix: Catch revert reasons and display human-readable error messages.
Not handling stuck transactions
mediumLow gas transactions can hang indefinitely.
Fix: Provide speedup/cancel options. Link to tools for stuck transactions.
Displaying raw error messages
mediumTechnical revert strings are meaningless to users.
Fix: Map common errors to friendly messages. Log technical details.
State Management
Polling too frequently
mediumExcessive RPC calls hit rate limits and waste resources.
Fix: Use appropriate polling intervals. Leverage websockets where available.
Not caching blockchain data
mediumRe-fetching same data on every render wastes RPC calls.
Fix: Use TanStack Query with wagmi for smart caching.
Stale data after transactions
highUI shows old balances/state after user's transaction confirms.
Fix: Invalidate queries after transaction success. Optimistic updates.
Mixing local and chain state incorrectly
mediumLocal state can diverge from blockchain causing confusion.
Fix: Use blockchain as source of truth. Local state for pending only.
Not handling block reorgs
lowConfirmed transactions can be undone in reorgs.
Fix: Wait for sufficient confirmations for important transactions.
Security Problems
Exposing private keys in frontend
criticalPrivate keys in client-side code can be stolen.
Fix: Never use private keys in frontend. Use wallet signatures only.
Not validating input before signing
highUsers might sign malicious transactions from manipulated UI.
Fix: Validate all inputs. Show clear transaction details before signing.
Trusting URL parameters blindly
highPhishing attacks can manipulate transaction parameters via URL.
Fix: Validate and sanitize all URL parameters. Confirm with user.
No phishing protection
mediumUsers can be tricked by lookalike domains.
Fix: Educate users. Consider ENS/domain verification features.
Storing sensitive data in localStorage
mediumlocalStorage is accessible to any script on the domain.
Fix: Never store private keys or sensitive tokens in localStorage.
UX Mistakes
No mobile responsiveness
highMany users access dApps via mobile wallet browsers.
Fix: Build mobile-first. Test in MetaMask Mobile, Rainbow, etc.
Complex onboarding for new users
mediumRequiring wallet setup immediately loses potential users.
Fix: Allow browsing without wallet. Consider embedded wallets for onboarding.
No loading states
mediumBlockchain operations are slow. Empty states confuse users.
Fix: Show skeletons and spinners. Explain why operations take time.
Displaying raw addresses
low0x742d35Cc6634C0532925a3b844Bc9e7595f0ab3 is unreadable.
Fix: Show ENS names when available. Truncate addresses (0x742d...0ab3).
Not explaining gas
mediumNew users don't understand why they need ETH for transactions.
Fix: Explain gas in simple terms. Show estimated costs in USD.
Development Practices
Not testing with real wallets
mediumMocked wallets behave differently than MetaMask.
Fix: Test with real wallets on testnets. Use Synpress for E2E tests.
Hardcoding contract addresses
lowMakes deployment to different networks painful.
Fix: Use environment variables or config files for addresses.
Using outdated libraries
mediumOld versions of ethers/web3 have bugs and security issues.
Fix: Keep dependencies updated. Consider migrating to viem/wagmi.
No error boundaries
mediumOne error crashes entire app instead of just affected component.
Fix: Wrap components in error boundaries. Show fallback UI.
Ignoring TypeScript types
mediumUsing 'any' types leads to runtime errors.
Fix: Use strict TypeScript. wagmi and viem have excellent types.