Skip to content

Commit cb7a21b

Browse files
committed
docs(mini-apps): add debugging guide for Mini Apps
1 parent 4a58455 commit cb7a21b

2 files changed

Lines changed: 320 additions & 4 deletions

File tree

docs/docs.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,12 @@
575575
"get-started/build-app"
576576
]
577577
},
578+
{
579+
"group": "Troubleshooting",
580+
"pages": [
581+
"mini-apps/guides/debugging"
582+
]
583+
},
578584
{
579585
"group": "Growth",
580586
"pages": [
@@ -716,7 +722,7 @@
716722
"destination": "/mini-apps/quickstart/migrate-to-standard-web-app"
717723
},
718724
{
719-
"source": "/mini-apps/troubleshooting/*",
725+
"source": "/mini-apps/troubleshooting/base-app-compatibility",
720726
"destination": "/mini-apps/quickstart/migrate-to-standard-web-app"
721727
},
722728
{
@@ -1713,7 +1719,7 @@
17131719
},
17141720
{
17151721
"source": "/builderkits/minikit/debugging",
1716-
"destination": "/base-app/build-with-minikit/debugging"
1722+
"destination": "/mini-apps/troubleshooting/debugging"
17171723
},
17181724
{
17191725
"source": "/builderkits/minikit/existing-app-integration",
@@ -2617,11 +2623,11 @@
26172623
},
26182624
{
26192625
"source": "/base-app/miniapps/debugging",
2620-
"destination": "/mini-apps/troubleshooting/common-issues"
2626+
"destination": "/mini-apps/troubleshooting/debugging"
26212627
},
26222628
{
26232629
"source": "/base-app/build-with-minikit/debugging",
2624-
"destination": "/mini-apps/troubleshooting/common-issues"
2630+
"destination": "/mini-apps/troubleshooting/debugging"
26252631
},
26262632
{
26272633
"source": "/mini-apps/design-ux/best-practices",
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
---
2+
title: "Debugging Mini Apps"
3+
description: "Diagnose and fix common issues when building Base Mini Apps, from local development to production."
4+
sidebarTitle: "Debugging"
5+
---
6+
7+
## Overview
8+
9+
Mini apps are harder to debug than regular web apps because they run inside Farcaster clients, not as standalone browser tabs. That means you need to debug iframe behavior, runtime context, manifest loading, and client wallet flows in addition to your app code. This guide shows you how to test local builds, inspect logs and network requests, validate your manifest, and fix the most common client-specific issues.
10+
11+
## Development environment setup
12+
13+
You cannot fully test a mini app by opening `http://localhost:3000` in a normal browser tab. Farcaster clients need a public HTTPS URL they can load inside their iframe-based runtime, so you need a tunnel during local development.
14+
15+
<Info>
16+
Use your local browser for layout and basic UI checks, but use a public tunnel to test the real mini app runtime.
17+
</Info>
18+
19+
<Tabs>
20+
<Tab title="ngrok">
21+
Install ngrok with npm:
22+
23+
```bash Terminal
24+
npm install -g ngrok
25+
```
26+
27+
Or install it with Homebrew:
28+
29+
```bash Terminal
30+
brew install ngrok
31+
```
32+
33+
Start a tunnel to your local app:
34+
35+
```bash Terminal
36+
ngrok http 3000
37+
```
38+
39+
Copy the generated `https://xxxx.ngrok-free.app` URL and paste it into **Warpcast Developer Tools > Preview Frames**.
40+
41+
<Warning>
42+
ngrok free-tier URLs change every time you restart the tunnel. Update your manifest each time the public URL changes.
43+
</Warning>
44+
</Tab>
45+
<Tab title="Cloudflare Tunnel">
46+
Install `cloudflared` with Homebrew:
47+
48+
```bash Terminal
49+
brew install cloudflare/cloudflare/cloudflared
50+
```
51+
52+
Or download it directly from Cloudflare.
53+
54+
Start a quick tunnel:
55+
56+
```bash Terminal
57+
cloudflared tunnel --url http://localhost:3000
58+
```
59+
60+
Quick tunnels do not require an account for local testing.
61+
62+
<Tip>
63+
Cloudflare tunnels stay stable during the session and do not require login, which makes them convenient for repeated debugging.
64+
</Tip>
65+
</Tab>
66+
</Tabs>
67+
68+
## Using the Farcaster Mini App Playground
69+
70+
The [Farcaster Mini App Playground](https://warpcast.com/~/developers/mini-apps) gives you a live preview of your mini app rendered inside a simulated Farcaster client.
71+
72+
<Steps>
73+
<Step title="Open the playground">
74+
Go to [warpcast.com/~/developers/mini-apps](https://warpcast.com/~/developers/mini-apps). You must be logged in to Warpcast on desktop.
75+
</Step>
76+
<Step title="Paste your tunnel URL">
77+
Paste your tunnel URL, such as `https://xxxx.ngrok-free.app`.
78+
</Step>
79+
<Step title="Preview the app">
80+
Click **Preview**.
81+
</Step>
82+
<Step title="Inspect the rendered client">
83+
The playground renders your app in an iframe that simulates the Farcaster mobile client.
84+
</Step>
85+
<Step title="Open DevTools">
86+
With the playground open, press `F12`. Console logs from your app appear in the host page DevTools.
87+
</Step>
88+
</Steps>
89+
90+
<Note>
91+
The playground uses your live tunnel, so code changes that trigger hot reload are reflected in real time after a refresh.
92+
</Note>
93+
94+
## Reading console logs and errors
95+
96+
Mini apps run inside an iframe, so logs appear in the host page DevTools, not in a separate browser window.
97+
98+
### Finding iframe logs in Chrome
99+
100+
Open **DevTools > Console**, then either filter by your tunnel URL or select the iframe context from the JavaScript context dropdown. If you stay in the top-level page context, you can miss the error that blocked your app from loading.
101+
102+
### Common console errors
103+
104+
| Error | Likely cause | Fix |
105+
|---|---|---|
106+
| `sdk.actions is not defined` | `@farcaster/frame-sdk` not initialized | Call `sdk.actions.ready()` inside `useEffect` after mount |
107+
| `Missing fc:frame meta tag` | Head metadata not set | Add `fc:frame` meta tag to `<head>` |
108+
| `Failed to fetch manifest` | `farcaster.json` not accessible | Check `/.well-known/farcaster.json` returns `200` |
109+
| `Wallet not connected` | Using `getEthereumProvider` before ready | Wait for `sdk.actions.ready()` to resolve |
110+
| `CORS error on API route` | API not allowing iframe origin | Add CORS headers to your API routes |
111+
| `accountAssociation invalid` | Manifest signed with wrong wallet | Re-sign using your Farcaster custody wallet |
112+
113+
## Inspecting network requests
114+
115+
Mini apps make network requests inside an iframe, so inspect them from the browser Network tab while the playground is open.
116+
117+
<Steps>
118+
<Step title="Load the app in the playground">
119+
Open the Warpcast playground with your app already loaded.
120+
</Step>
121+
<Step title="Open the Network tab">
122+
Open **DevTools > Network**.
123+
</Step>
124+
<Step title="Filter requests">
125+
Filter by **Fetch/XHR** to focus on API calls.
126+
</Step>
127+
<Step title="Inspect failures">
128+
Look for failed requests in red, then click each one to inspect request and response details.
129+
</Step>
130+
<Step title="Check the manifest endpoint">
131+
Verify that `/.well-known/farcaster.json` returns `200` with `Content-Type: application/json`.
132+
</Step>
133+
</Steps>
134+
135+
<Tip>
136+
Use **Preserve log** in DevTools to keep network logs across page navigations inside the iframe.
137+
</Tip>
138+
139+
## Manifest validation
140+
141+
The `farcaster.json` manifest is the most common source of bugs. Validate it directly before you debug anything more complex.
142+
143+
```bash Terminal
144+
curl -s https://yourdomain.com/.well-known/farcaster.json | jq .
145+
```
146+
147+
<Check>
148+
`accountAssociation.header` is present and non-empty
149+
</Check>
150+
151+
<Check>
152+
`accountAssociation.payload` is present
153+
</Check>
154+
155+
<Check>
156+
`accountAssociation.signature` is present
157+
</Check>
158+
159+
<Check>
160+
`frame.name` is set
161+
</Check>
162+
163+
<Check>
164+
`frame.homeUrl` matches your actual deployment URL exactly
165+
</Check>
166+
167+
<Check>
168+
`frame.iconUrl` returns `200`
169+
</Check>
170+
171+
<Check>
172+
`frame.primaryCategory` is set for search and discovery
173+
</Check>
174+
175+
<Warning>
176+
`homeUrl` must exactly match the domain you used when signing the manifest. A mismatch causes `accountAssociation` validation to fail silently.
177+
</Warning>
178+
179+
## setFrameReady / sdk.actions.ready() — the most common mistake
180+
181+
The Farcaster client shows a splash screen until your app calls `ready()`. If you never call it, the splash screen stays visible forever.
182+
183+
### MiniKit
184+
185+
Use `setFrameReady()` from `useMiniKit()`.
186+
187+
```tsx App.tsx lines expandable wrap highlight={2,4-8}
188+
import { useEffect } from 'react';
189+
import { useMiniKit } from '@coinbase/onchainkit/minikit';
190+
191+
export function App() {
192+
const { setFrameReady, isFrameReady } = useMiniKit();
193+
194+
useEffect(() => {
195+
if (!isFrameReady) {
196+
setFrameReady();
197+
}
198+
}, [setFrameReady, isFrameReady]);
199+
200+
return <div>Your app</div>;
201+
}
202+
```
203+
204+
### Raw SDK
205+
206+
Use `sdk.actions.ready()`.
207+
208+
```tsx App.tsx lines wrap highlight={1,5}
209+
import sdk from '@farcaster/frame-sdk';
210+
import { useEffect } from 'react';
211+
212+
export function App() {
213+
useEffect(() => {
214+
sdk.actions.ready();
215+
}, []);
216+
217+
return <div>Your app</div>;
218+
}
219+
```
220+
221+
<Warning>
222+
Do not call `setFrameReady()` conditionally or after an async operation without handling errors. If the call throws, the splash screen never dismisses.
223+
</Warning>
224+
225+
## Context not available (testing outside Farcaster)
226+
227+
`sdk.context` and `useMiniKit().context` return `null` when you open your app in a regular browser instead of inside Farcaster. That is expected. Mini apps are designed to run inside Farcaster clients.
228+
229+
```tsx App.tsx lines wrap highlight={2-5}
230+
import { useMiniKit } from '@coinbase/onchainkit/minikit';
231+
232+
export function App() {
233+
const { context } = useMiniKit();
234+
235+
if (!context) {
236+
return <div>Open this app inside Farcaster or the Warpcast playground.</div>;
237+
}
238+
239+
return <div>Your app</div>;
240+
}
241+
```
242+
243+
<Tip>
244+
Add a fallback UI for non-Farcaster environments. It also helps local development before you set up a tunnel.
245+
</Tip>
246+
247+
## Wallet issues
248+
249+
Wallet connection can work in a normal browser and still fail inside Farcaster because Coinbase Wallet in Farcaster uses a different provider than MetaMask or other injected wallets.
250+
251+
Always use `sdk.wallet.getEthereumProvider()` or `@farcaster/frame-wagmi-connector`, not `window.ethereum` directly.
252+
253+
```ts wagmi.ts lines wrap highlight={1,3}
254+
import { frameConnector } from '@farcaster/frame-wagmi-connector';
255+
256+
const config = createConfig({
257+
connectors: [frameConnector()],
258+
// ...
259+
});
260+
```
261+
262+
<Warning>
263+
Sign In with Farcaster inside Coinbase Wallet can require a deeplink back to Warpcast for accounts created there. Prefer wallet auth for a smoother user experience.
264+
</Warning>
265+
266+
## Production checklist
267+
268+
<Check>
269+
App is deployed at a public HTTPS URL
270+
</Check>
271+
272+
<Check>
273+
`/.well-known/farcaster.json` returns `200` and valid JSON
274+
</Check>
275+
276+
<Check>
277+
`setFrameReady()` or `sdk.actions.ready()` is called on mount
278+
</Check>
279+
280+
<Check>
281+
Manifest `homeUrl` exactly matches the deployment URL
282+
</Check>
283+
284+
<Check>
285+
Manifest is signed with your Farcaster custody wallet
286+
</Check>
287+
288+
<Check>
289+
`primaryCategory` is set in the manifest
290+
</Check>
291+
292+
<Check>
293+
The app handles `context === null` gracefully
294+
</Check>
295+
296+
<Check>
297+
There are no `window.ethereum` references for mini app wallet flows
298+
</Check>
299+
300+
<Check>
301+
CORS headers are set on API routes called from the iframe
302+
</Check>
303+
304+
## Related guides
305+
306+
- [Mini Apps quickstart](/mini-apps/quickstart/create-new-miniapp)
307+
- [Common Issues & Debugging](/mini-apps/troubleshooting/common-issues)
308+
- [MiniKit overview](/builderkits/minikit/overview)
309+
- [MiniKit quickstart](/builderkits/minikit/quickstart)
310+
- [Loading your app](https://miniapps.farcaster.xyz/docs/guides/loading)

0 commit comments

Comments
 (0)