Skip to content

Commit a488900

Browse files
authored
added embed metadata (#428)
1 parent 7f83348 commit a488900

File tree

3 files changed

+341
-242
lines changed

3 files changed

+341
-242
lines changed

docs/docs.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,6 @@
446446
"mini-apps/technical-guides/data-driven-growth",
447447
"mini-apps/technical-guides/search-and-discovery",
448448
"mini-apps/technical-guides/sharing-and-social-graph",
449-
"mini-apps/technical-guides/embeds-and-previews",
450449
"mini-apps/technical-guides/links",
451450
"mini-apps/technical-guides/sign-manifest"
452451
]
Lines changed: 69 additions & 241 deletions
Original file line numberDiff line numberDiff line change
@@ -1,272 +1,100 @@
11
---
22
title: Embeds & Previews
3-
description: Turn every user action into organic growth with shareable, metadata-powered embeds that drive engagement and discovery.
3+
description: Mini apps use metadata to create embeds when users share links. The embed shows a preview image and launch button..
44
---
55

6-
> **What you'll learn**
7-
> By the end of this guide, you'll be able to:
8-
> - Understand how embeds and metadata work together to create rich social previews
9-
> - Choose between static and dynamic embeds for different use cases
10-
> - Debug and optimize embeds for maximum performance and engagement
11-
12-
## Why Sharing Matters
13-
14-
Sharing is one of the fastest and most cost-effective ways to grow your Mini App user base.
15-
16-
When a user shares your app into a feed (such as Base App or Farcaster), the platform generates a **rich embed** — a visual preview complete with your branding, imagery, and call-to-action button that appears directly in social feeds.
17-
18-
Every share:
19-
20-
- **Increases reach** — friends and followers see your app instantly
21-
- **Drives engagement** — visually compelling embeds get more clicks than plain links
22-
- **Improves ranking** — shared apps are more likely to appear in category leaderboards
23-
- **Creates viral loops** — great experiences encourage users to share with their networks
24-
25-
## Metadata and Embeds
26-
27-
### How Metadata Creates Embeds
28-
29-
When someone shares your Mini App link, platforms like Base App don't just show a plain URL. Instead, they fetch **metadata** from your page and use it to generate a rich **embed** — a visual preview card with your image, title, and call-to-action button.
30-
31-
The metadata acts as instructions that tell the platform exactly how to display your Mini App in feeds.
32-
33-
<Frame caption="How metadata transforms into embeds">
34-
<img src="/images/minikit/Diagram.png" alt="How embed data is rendered" />
35-
</Frame>
36-
37-
**The complete metadata-to-embed process:**
38-
39-
<Steps>
40-
<Step title="User shares your link">
41-
User clicks share or pastes your Mini App URL into a social feed (Base App, Farcaster).
42-
</Step>
43-
44-
<Step title="Platform fetches metadata">
45-
The platform makes a request to your URL and reads the `<meta>` tags in your HTML to understand how to display your app.
46-
</Step>
47-
48-
<Step title="Metadata becomes embed">
49-
Platform transforms your metadata into a rich visual embed with image, title, description, and interactive button.
50-
</Step>
51-
52-
<Step title="Embed appears in feed">
53-
Your Mini App appears as an attractive, clickable card that users can launch directly from their feed.
54-
</Step>
55-
</Steps>
56-
57-
### Metadata Structure
58-
59-
Your metadata consists of specific HTML meta tags that define each part of the embed:
60-
61-
```html index.html
62-
<meta name="fc:frame" content='{
63-
"version":"next",
64-
"imageUrl":"https://your-app.com/embed-image",
65-
"button":{
66-
"title":"Play Now",
67-
"action":{
68-
"type":"launch_frame",
69-
"name":"Your App Name",
70-
"url":"https://your-app.com"
71-
}
72-
}
73-
}' />
74-
```
75-
76-
Each piece of metadata directly corresponds to a visual element in the embed:
77-
78-
- `imageUrl` → The main visual that appears in the embed
79-
- `button.title` → Text on the call-to-action button
80-
- `action.name` → App name displayed in the embed
81-
- `action.url` → Where users go when they click the embed
82-
83-
### Embed Appearance in Feeds
84-
6+
<Panel>
857
<Frame caption="Mini App embed in social feed">
86-
<img src="/images/minikit/feed_mini.jpg" alt="Mini app feed" className="h-[220px] w-auto"/>
8+
<img src="/images/minikit/feed_mini.jpg" alt="Mini app feed" className="h-[220px] w-auto"/>
879
</Frame>
88-
89-
### Manifest vs Embed Metadata
90-
91-
Your Mini App uses two types of metadata:
92-
93-
#### Manifest file
94-
95-
Purpose: App registration and discovery
96-
97-
Located at `/.well-known/farcaster.json`, this file contains your app's basic information for Base App's directory.
98-
99-
<Warning>
100-
Mini Apps require a complete manifest. Read the [manifest requirements](/mini-apps/features/manifest#example-manifest).
101-
</Warning>
102-
103-
#### Embed metadata
104-
105-
Purpose: Embed generation when shared
106-
107-
Located in your HTML `<head>` tags, this metadata creates the rich embeds when users share your app.
108-
109-
```html index.html
110-
<meta name="fc:frame" content='{
111-
"version":"next",
112-
"imageUrl":"https://your-app.com/embed-image",
113-
"button":{
114-
"title":"Play Now",
115-
"action":{
116-
"type":"launch_frame",
117-
"name":"Your App Name",
118-
"url":"https://your-app.com"
119-
}
120-
}
121-
}' />
122-
```
123-
124-
This controls how your embeds appear in social feeds.
125-
126-
### Best Practices for Metadata
127-
128-
- Image optimization: Use 3:2 aspect ratio
129-
- Clear value proposition in button and text
130-
- Visual consistency with product UI
131-
- Fast loading for metadata endpoints
132-
- Validate across platforms pre‑launch
133-
134-
## Sharing
135-
136-
### Adding Share Functionality
137-
138-
Prompt users to share during key accomplishment moments using MiniKit’s compose hook.
139-
140-
```ts ComposeCastButton.tsx
141-
import { useComposeCast } from '@coinbase/onchainkit/minikit';
142-
143-
export default function ComposeCastButton() {
144-
const { composeCast } = useComposeCast();
145-
146-
const handleCompose = () => {
147-
composeCast({
148-
text: 'Just minted an awesome NFT using @coinbase OnchainKit! ',
149-
});
150-
};
151-
152-
const handleComposeWithEmbed = () => {
153-
composeCast({
154-
text: 'Check out this amazing Mini App!',
155-
embeds: ['https://your-mini-app-url.com'],
156-
});
157-
};
158-
159-
return (
160-
<div>
161-
<button onClick={handleCompose}>Share Achievement</button>
162-
<button onClick={handleComposeWithEmbed}>Share Frame</button>
163-
</div>
164-
);
165-
}
10+
</Panel>
11+
## Implementation
12+
Add this meta tag to the `<head>` section of any page you want to make shareable:
13+
14+
```html metadata
15+
<!DOCTYPE html>
16+
<html lang="en">
17+
<head>
18+
<title>My Mini App</title>
19+
<meta name="fc:frame" content='{"version":"next","imageUrl":"https://example.com/preview.png","button":{"title":"Open App","action":{"type":"launch_frame","url":"https://example.com"}}}' />
20+
</head>
21+
<body>
22+
<!-- Your app content -->
23+
</body>
24+
</html>
16625
```
26+
Each page can have different metadata to create unique embeds.
16727

16828
<Tip>
169-
Strategic sharing moments:
170-
171-
- After completing a quiz
172-
- After minting an NFT
173-
- After beating a challenge
174-
- After reaching a milestone
29+
For Next.js projects, use the [Metadata API](https://nextjs.org/docs/app/building-your-application/optimizing/metadata) to generate the `fc:frame` meta tag dynamically.
17530
</Tip>
17631

177-
### From the Base App UI
178-
179-
Users can also share directly from your app's detail view in the Base app through the built‑in share functionality.
32+
## Schema
18033

181-
<Frame caption="Share button in the Base app UI">
182-
<img src="/images/minikit/share-button-ui.jpg" alt="Share button in Base app" className="h-[220px] w-auto"/>
183-
</Frame>
34+
<Card>
35+
<ParamField path="version" type="string" required>
36+
Version of the embed. Must be `"1"` or `"next"`.
37+
</ParamField>
18438

185-
## Embed Types
39+
<ParamField path="imageUrl" type="string" required>
40+
Image URL for the embed. Must be 3:2 aspect ratio, maximum 10MB, maximum 1024 characters.
41+
</ParamField>
18642

187-
### Static embeds
43+
<ParamField path="button" type="object" required>
44+
Button configuration object.
45+
</ParamField>
46+
</Card>
18847

189-
Use a single, unchanging image and text for all shares. Best for consistency and speed.
48+
### Button Configuration
19049

191-
### Dynamic embeds
50+
Defines the launch button that appears on the embed.
19251

193-
Generate metadata per user or event for personalization and FOMO. Ensure fast response (< 5s) and caching strategy.
52+
<Card>
53+
<ParamField path="button.title" type="string" required>
54+
Button text. Maximum 32 characters.
55+
</ParamField>
19456

195-
## Implementation
57+
<ParamField path="button.action" type="object" required>
58+
Action configuration object. Maximum 1024 characters.
59+
</ParamField>
60+
</Card>
19661

197-
### With MiniKit (Next.js)
62+
### Action Configuration
19863

199-
```ts layout.tsx
200-
export async function generateMetadata(): Promise<Metadata> {
201-
const URL = process.env.NEXT_PUBLIC_URL;
202-
return {
203-
title: process.env.NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAME,
204-
description: "Your Mini App description here",
205-
other: {
206-
"fc:frame": JSON.stringify({
207-
version: "next",
208-
imageUrl: process.env.NEXT_PUBLIC_APP_HERO_IMAGE,
209-
button: {
210-
title: `Launch ${process.env.NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAME}`,
211-
action: {
212-
type: "launch_frame",
213-
name: process.env.NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAME,
214-
url: URL,
215-
splashImageUrl: process.env.NEXT_PUBLIC_SPLASH_IMAGE,
216-
splashBackgroundColor: process.env.NEXT_PUBLIC_SPLASH_BACKGROUND_COLOR,
217-
},
218-
},
219-
}),
220-
},
221-
};
222-
}
223-
```
64+
Specifies what happens when the embed button is clicked.
22465

225-
### Without MiniKit
66+
<Card>
67+
<ParamField path="button.action.type" type="string" required>
68+
Action type. Must be `"launch_frame"`.
69+
</ParamField>
22670

227-
```html index.html
228-
<meta name="fc:frame" content='{"version":"next","imageUrl":"https://your-app.com/embed-image","button":{"title":"Play Now","action":{"type":"launch_frame","name":"Your App Name","url":"https://your-app.com"}}}' />
229-
```
71+
<ParamField path="button.action.url" type="string">
72+
App URL to open. Defaults to the full URL of the page including query parameters. Maximum 1024 characters.
73+
</ParamField>
23074

231-
## Debugging
75+
<ParamField path="button.action.name" type="string">
76+
Application name. Maximum 32 characters. Defaults to manifest name.
77+
</ParamField>
23278

233-
### Tools
79+
<ParamField path="button.action.splashImageUrl" type="string">
80+
Splash screen image URL. Must be 200x200 pixels. Maximum 32 characters. Defaults to manifest splash image.
81+
</ParamField>
23482

235-
<Card title="Base Build Preview Tool" icon="bug" href="https://base.dev/preview">
236-
Test how your app will appear in the Base app by validating your manifest, embeds, and account association
83+
<ParamField path="button.action.splashBackgroundColor" type="string">
84+
Splash screen background color. Must be hex color code. Defaults to manifest splash background color.
85+
</ParamField>
23786
</Card>
23887

239-
### Common issues
24088

241-
<AccordionGroup>
242-
<Accordion title="Embed not showing or incorrect">
243-
Check image dimensions, required `fc:frame`, JSON validity, and URL accessibility.
244-
</Accordion>
245-
<Accordion title="Embeds not updating">
246-
Review cache headers, repost to refresh, wait ~10–15 minutes for caches.
247-
</Accordion>
248-
<Accordion title="Slow generation">
249-
Optimize image generation, pre‑generate, use serverless, compress assets.
250-
</Accordion>
251-
</AccordionGroup>
252-
253-
<Warning>
254-
Set `Cache-Control` carefully: long enough for performance (300–600s), short enough for quick updates.
255-
</Warning>
256-
257-
## Next Steps
258-
259-
<Steps>
260-
<Step title="Choose your embed strategy" />
261-
<Step title="Implement metadata generation" />
262-
<Step title="Add strategic share points" />
263-
<Step title="Test and optimize" />
264-
</Steps>
265-
266-
Continue with:
267-
268-
- [Search and Discovery](/mini-apps/technical-guides/search-and-discovery)
269-
- [Manifest](/mini-apps/core-concepts/manifest)
89+
## Related Concepts
27090

91+
<CardGroup cols={2}>
92+
<Card title="Search and Discovery" href="/mini-apps/technical-guides/search-and-discovery">
93+
Learn how your manifest powers search indexing and category placement in the Base app discovery features.
94+
</Card>
27195

96+
<Card title="Sharing and Social Graph" href="/mini-apps/technical-guides/sharing-and-social-graph">
97+
Learn how to maximize sharing, social engagement, and viral growth for your Mini App using Base's social graph features.
98+
</Card>
99+
</CardGroup>
272100

0 commit comments

Comments
 (0)