Skip to content

Commit 2233faf

Browse files
committed
Update Onboarding doc and Links doc
1 parent a4a3121 commit 2233faf

File tree

2 files changed

+192
-26
lines changed

2 files changed

+192
-26
lines changed

docs/mini-apps/features/links.mdx

Lines changed: 150 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,158 @@
11
---
22
title: Links
3-
description: Handle closing the frame and opening external URLs safely
3+
description: Handle external navigation and URL interactions safely across clients
44
---
55

6-
Sdk options for external links
6+
When building Mini Apps, proper link handling is crucial for providing a consistent user experience across different clients. This guide outlines best practices for external navigation and URL interactions.
77

8+
## Core Principles
89

9-
Deep links coming soon
10+
### Use SDK Actions for Cross-Client Compatibility
1011

12+
**Always use official SDK functions instead of static URLs.** Static URLs can break cross-client compatibility and may leave users unable to complete actions in your Mini App.
13+
14+
<Warning>
15+
Avoid using direct HTML links (`<a href="">`, `<Link href="">`) or static URLs in your Mini App. These approaches don't work consistently across different clients and can create poor user experiences.
16+
</Warning>
17+
18+
## External Navigation
19+
20+
### Opening External URLs
21+
22+
Use `sdk.actions.openUrl()` to safely open external websites in the client's in-app browser:
23+
24+
```javascript
25+
import { sdk } from '@farcaster/frame-sdk';
26+
27+
// ✅ Correct: Use SDK action
28+
const openExternalSite = () => {
29+
sdk.actions.openUrl('https://example.com');
30+
};
31+
32+
// ❌ Incorrect: Direct HTML link
33+
// <a href="https://example.com">Visit Site</a>
34+
```
35+
36+
### Composing Casts
37+
38+
Use `sdk.actions.composeCast()` instead of composer intent URLs:
39+
40+
```javascript
41+
import { sdk } from '@farcaster/frame-sdk';
42+
43+
// ✅ Correct: Use SDK action
44+
const shareContent = () => {
45+
sdk.actions.composeCast({
46+
text: 'Check out this Mini App!',
47+
embeds: ['https://yourminiapp.com']
48+
});
49+
};
50+
51+
// ❌ Incorrect: Composer intent URLs
52+
// window.open('https://farcaster.com/~/compose?text=...')
53+
```
54+
55+
## Best Practices
56+
57+
### 1. Prioritize SDK Actions
58+
59+
Before implementing any navigation or linking functionality:
60+
61+
1. Check if an official SDK action exists for your use case
62+
2. Use the SDK action instead of crafting custom URLs
63+
3. Test across multiple clients to ensure compatibility
64+
65+
### 2. Handle Unsupported Features Gracefully
66+
67+
When using features that may not be supported in all clients:
68+
69+
```javascript
70+
import { sdk } from '@farcaster/frame-sdk';
71+
72+
const handleExternalLink = (url) => {
73+
try {
74+
sdk.actions.openUrl(url);
75+
} catch (error) {
76+
// Fallback behavior for unsupported clients
77+
console.log('External navigation not supported');
78+
}
79+
};
80+
```
81+
82+
### 3. Avoid Client-Specific URLs
83+
84+
Don't hardcode URLs specific to particular clients (like Warpcast URLs). Instead, use SDK actions that work across all supported clients.
85+
86+
## Common Patterns
87+
88+
### Navigation Buttons
89+
90+
```javascript
91+
import { sdk } from '@farcaster/frame-sdk';
92+
93+
const NavigationComponent = () => {
94+
const handleExternalLink = () => {
95+
sdk.actions.openUrl('https://docs.example.com');
96+
};
97+
98+
const handleShare = () => {
99+
sdk.actions.composeCast({
100+
text: 'Just used this amazing Mini App!',
101+
embeds: [window.location.href]
102+
});
103+
};
104+
105+
return (
106+
<div>
107+
<button onClick={handleExternalLink}>
108+
View Documentation
109+
</button>
110+
<button onClick={handleShare}>
111+
Share This App
112+
</button>
113+
</div>
114+
);
115+
};
116+
```
117+
118+
### Conditional Navigation
119+
120+
```javascript
121+
import { sdk } from '@farcaster/frame-sdk';
122+
123+
const ConditionalNavigation = () => {
124+
const context = sdk.context;
125+
126+
const handleNavigation = () => {
127+
// Adapt behavior based on client capabilities
128+
if (context.client.clientFid) {
129+
sdk.actions.openUrl('https://app-specific-url.com');
130+
} else {
131+
// Fallback for other clients
132+
window.open('https://fallback-url.com', '_blank');
133+
}
134+
};
135+
136+
return (
137+
<button onClick={handleNavigation}>
138+
Open External Resource
139+
</button>
140+
);
141+
};
142+
```
143+
144+
## Migration Guide
145+
146+
If your Mini App currently uses static URLs or direct links, update them using these patterns:
147+
148+
| Current Implementation | Recommended SDK Action |
149+
|----------------------|----------------------|
150+
| `<a href="https://external.com">` | `sdk.actions.openUrl('https://external.com')` |
151+
| `window.open('https://farcaster.com/~/compose?text=...')` | `sdk.actions.composeCast({ text: '...', embeds: [...] })` |
152+
| Farcaster-specific deeplinks | Use appropriate SDK action |
153+
| Direct profile links | Use SDK actions for profile navigation when available |
154+
155+
## Future Considerations
156+
157+
While deeplinks are not currently supported, they are on the roadmap. When they become available, this documentation will be updated with specific implementation guidance. In the meantime, continue using SDK actions for the most reliable cross-client experience.
11158

docs/mini-apps/growth/optimize-onboarding.mdx

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,74 +5,93 @@ description: Reduce friction with wallet‑optional flows and clear value moment
55

66
Optimize your onboarding flow to increase user engagement and retention. This guide outlines the best practices that will keep your users in-app and engaged.
77

8-
### Goals
8+
### Overview
99

10-
- Make first interaction instant and non-blocking
11-
- Authenticate only when a backend requires it; defer prompts until needed
10+
Deliver value instantly and avoid blocking actions.
11+
12+
- Make the first interaction instant and non-blocking
13+
- Authenticate only when required for security purposes and defer prompts until necessary
1214
- Prefer the built-in Base Account; only offer connect/switch for alternate wallets, never gating
1315
- Use progressive disclosure tied to intent (buy, post, personalize)
14-
- Keep users in-app with SDK actions; avoid fragile deeplinks
16+
- Keep users in-app with [SDK actions for links](/mini-apps/features/links); avoid fragile static urls
1517

1618
### Recommended onboarding flow
1719

1820
<Steps>
19-
<Step title="First render (no prompts)">
21+
<Step title="First render">
2022
- Show immediate value (demo content, sample state, or read-only mode)
21-
- Use Mini App `context` of user profile to instantly personalize
22-
- Primary CTA leads to a meaningful action; no upfront login/connect dialogs
23+
- Personalize instantly with [`context`](/mini-apps/technical-reference/minikit/provider-and-initialization) of the user's profile to instantly personalize
24+
- Display one clear CTA that leads to a meaningful action (e.g. "Post a message", "Buy a token", "Follow a user")
2325
</Step>
2426

2527
<Step title="User initiates a protected action">
26-
- Backend needed: trigger Sign In with Farcaster (SIWF) / Quick Auth at this moment only
27-
- Onchain action: use the Base Account automatically; no explicit wallet connect flow
28+
- Trigger Sign In with Farcaster (SIWF) / Quick Auth only when needed per [Authentication](/mini-apps/features/Authentication)
29+
- For onchain actions, use the Base Account automatically. Eliminate explicit wallet connect flows
2830
- Alternate wallets: offer a non-blocking connect/switch option without gating exploration
2931
</Step>
3032

3133
<Step title="Celebrate and amplify">
32-
- After success, prompt social actions via SDK (e.g., compose cast, view profile)
33-
- Offer next step: save progress, follow, or share
34+
- After success, prompt social actions via [SDK actions](/mini-apps/features/links) and [Sharing & Social Graph](/mini-apps/features/sharing-and-social-graph)
35+
- Offer next step: save, follow, or share — optimize with [Search & Discovery](/mini-apps/features/search-and-discovery)
3436
</Step>
3537
</Steps>
3638

3739
### UX patterns that work
3840

41+
<Tip>
3942
- Progressive prompts: ask only when needed (buy, post, personalize)
4043
- Clear copy: explain why you’re asking ("Sign in to save your score")
44+
</Tip>
45+
4146
- One-time deep link (Connect Account users): if SIWF requires a one-time Farcaster link to register auth address, message it as a quick, one-time setup and return the user seamlessly
4247
- Friendly fallbacks: if auth is skipped or fails, allow continued browsing in read-only mode
4348

4449
### Authentication and wallet guidance
4550

46-
- Authentication
47-
- Only when your backend needs a verified user
48-
- Use SIWF/Quick Auth to issue a session (JWT) when required
49-
- Do not treat Mini App context as primary auth (it can be spoofed)
50-
- See: [Authentication](/mini-apps/features/Authentication)
51+
#### Authentication
52+
53+
- Only when your backend needs a verified user
54+
- Use SIWF/Quick Auth to issue a session (JWT) when required
55+
56+
<Warning>
57+
Do not treat Mini App context as primary auth (it can be spoofed)
58+
</Warning>
59+
60+
Read more in [Authentication](/mini-apps/features/Authentication).
5161

52-
- Wallet
53-
- Base App provides an in-app Base Account; prefer using it automatically
54-
- Do not show a connect button on first load in Base App
55-
- If you support other wallets, show connect/switch as optional and non-blocking
56-
- Use OnchainKit Wallet or Wagmi hooks as needed
62+
#### Wallets
63+
- Base App provides an in-app Base Account. This should be the default wallet used by your app to streamline interactions.
64+
- Do not show a connect button on first load
65+
- If you support other wallets, show connect/switch as optional and non-blocking
66+
- Use the OnchainKit Wallet component or Wagmi hooks as needed
5767

5868
### Do not use raw deeplinks
5969

70+
<Warning>
6071
- Always use official SDK actions for cross-client compatibility (e.g., compose cast, view profile)
6172
- This prevents dead ends and ensures consistent behavior across hosts
62-
- See: [Links](/mini-apps/features/links)
73+
</Warning>
74+
75+
Learn how to implement them with [SDK actions](/mini-apps/features/links).
6376

6477
### Measure activation and iterate
6578

79+
<Info>
6680
- Define activation as the first successful protected action (e.g., first post, first onchain action)
6781
- Track funnel: first render → intent click → auth/wallet prompt → success → share/save
82+
</Info>
83+
6884
- Break down Create Account vs Connect Account behavior to spot friction
6985
- See: Base Build Analytics (coming soon)
7086

7187
### Implementation checklist
7288

89+
<Check>
7390
- Landing screen is usable without auth or wallet prompts
74-
- Use MiniKit context for analytics only; avoid using it as primary auth
7591
- Trigger SIWF/Quick Auth only when backend needs it
92+
</Check>
93+
94+
- Use MiniKit context for analytics only; avoid using it as primary auth
7695
- Use Base Account seamlessly for onchain actions; no upfront connect flow
7796
- If supporting alternate wallets, provide optional, non-blocking connect/switch
7897
- Use SDK actions for social flows (compose/view) instead of deeplinks

0 commit comments

Comments
 (0)