/swap. The widget reads window and localStorage on mount, so it must be client-only. We use next/dynamic with ssr: false.
File tree
Install
src/app/layout.tsx
src/app/swap/widget.tsx
The widget itself, wrapped in dynamic(... { ssr: false }).
src/app/swap/page.tsx
.env.local
next dev after creating or changing .env.local.
Run it
Why ssr: false?
The widget reads window, localStorage, and prefers-color-scheme on mount. None of those exist during server rendering. dynamic(... { ssr: false }) defers the import to the browser, so the widget only ever runs client-side.
If you forget ssr: false, you’ll see a hydration-mismatch error or a window is not defined exception.
With dApp-mode wallet
If your app already manages the wallet (wagmi, RainbowKit, or any other host-side wallet library), switch to dApp mode and pass the provider:Related pages
- Install — package install and basic setup.
- Wallet management — standalone vs dApp mode.
- Compatibility — full SSR notes.
- React example — same widget on a Vite stack.