From 3203aed33423422c8f800b3a1a0d49a072f471db Mon Sep 17 00:00:00 2001 From: sohey Date: Mon, 27 Oct 2025 13:35:28 +0100 Subject: [PATCH 1/9] added embed metadata --- docs/docs.json | 2 + .../technical-guides/dynamic-embeds.mdx | 153 ++++++++++ .../technical-guides/embeds-and-previews.mdx | 272 ------------------ 3 files changed, 155 insertions(+), 272 deletions(-) create mode 100644 docs/mini-apps/technical-guides/dynamic-embeds.mdx delete mode 100644 docs/mini-apps/technical-guides/embeds-and-previews.mdx diff --git a/docs/docs.json b/docs/docs.json index d36e0dba..ab0f1614 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -454,7 +454,9 @@ "group": "Technical Guides", "pages": [ "mini-apps/technical-guides/sign-manifest", + "mini-apps/technical-guides/dynamic-embeds", "mini-apps/technical-guides/neynar-notifications" + ] }, { diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx new file mode 100644 index 00000000..17b83ba5 --- /dev/null +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -0,0 +1,153 @@ +--- +title: Dynamic OG Image Generation +description: Generate real-time preview images for Base mini app embeds +--- + +Dynamic images are the first thing users see when they encounter your mini app in their feed. Each share can display unique, contextual content tailored to drive engagement. + + + + How embed data is rendered + +When users share your mini app `URL`, the Base app requests your page, reads the fc:miniapp metadata, and fetches the `OGImageUrl`. You can serve either a static file (same image for everyone) or a dynamic endpoint that generates unique images on-demand based on URL parameters. + + + +This guide uses Next.js App Router with ImageResponse for implementation. The patterns apply to any framework with server-side rendering. + + +## Implementation + + + +Pass the user's FID to your image endpoint via URL parameters. + +```tsx app/dynamic-image-example/[id]/page.tsx +import { Metadata } from "next"; + +const appUrl = process.env.NEXT_PUBLIC_URL; + +export async function generateMetadata({ + params, +}: { + params: Promise<{ id: string }>; +}): Promise { + const { id } = await params; + + const imageUrl = `${appUrl}/api/og/example/${id}`; + + const frame = { + version: "next", + imageUrl: imageUrl, + button: { + title: "Launch App", + action: { + type: "launch_frame", + name: "Mini App", + url: appUrl, + splashImageUrl: `${appUrl}/images/splash.png`, + splashBackgroundColor: "#f7f7f7", + }, + }, + }; + + return { + title: "Mini App", + other: { + "fc:frame": JSON.stringify(frame), + }, + }; +} + +export default function DynamicImagePage() { + return
Your app content
; +} +``` + +The `id` parameter becomes part of the image URL: `/api/og/example/123` +
+ + +Create an API route that reads the FID and generates a unique image. + +```tsx app/api/og/example/[id]/route.tsx +import { ImageResponse } from "next/og"; + +export const dynamic = "force-dynamic"; + +const size = { + width: 600, + height: 400, +}; + +export async function GET( + request: Request, + { params }: { params: Promise<{ id: string }> } +) { + const { id } = await params; + + return new ImageResponse( + ( +
+
+ User FID: {id} +
+
+ ), + { + ...size, + } + ); +} +``` + +Each unique FID generates a different image. +
+ + +Verify your dynamic image generates correctly. + +```bash +curl http://localhost:3000/api/og/example/123 > test.png +open test.png +``` + +Each different FID produces a unique image. + +
+ +## Troubleshooting + +**Gray images in embeds** +- Generation takes >2s. Use cached data sources instead of database queries. +- Verify image dimensions are 3:2 ratio (1200x800px). + +**Stale data showing** +- Decrease `max-age` to match your data update frequency. +- Add version parameter to URL: `?v=2` to force refresh. + +**High function costs** +- Increase `max-age` to reduce regeneration frequency. +- Verify `Cache-Control` header includes `public` directive. + +**Embed not displaying** +- Check metadata exists: `curl https://your-domain.com/page | grep "fc:miniapp"` +- Validate with debugger: https://warpcast.com/~/developers/frames/debug + + +- [Search and Discovery](/mini-apps/troubleshooting/how-search-works) +- [Manifest](/mini-apps/core-concepts/manifest) + + + diff --git a/docs/mini-apps/technical-guides/embeds-and-previews.mdx b/docs/mini-apps/technical-guides/embeds-and-previews.mdx deleted file mode 100644 index 8c7a363b..00000000 --- a/docs/mini-apps/technical-guides/embeds-and-previews.mdx +++ /dev/null @@ -1,272 +0,0 @@ ---- -title: Embeds & Previews -description: Turn every user action into organic growth with shareable, metadata-powered embeds that drive engagement and discovery. ---- - -> **What you'll learn** -> By the end of this guide, you'll be able to: -> - Understand how embeds and metadata work together to create rich social previews -> - Choose between static and dynamic embeds for different use cases -> - Debug and optimize embeds for maximum performance and engagement - -## Why Sharing Matters - -Sharing is one of the fastest and most cost-effective ways to grow your Mini App user base. - -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. - -Every share: - -- **Increases reach** — friends and followers see your app instantly -- **Drives engagement** — visually compelling embeds get more clicks than plain links -- **Improves ranking** — shared apps are more likely to appear in category leaderboards -- **Creates viral loops** — great experiences encourage users to share with their networks - -## Metadata and Embeds - -### How Metadata Creates Embeds - -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. - -The metadata acts as instructions that tell the platform exactly how to display your Mini App in feeds. - - - How embed data is rendered - - -**The complete metadata-to-embed process:** - - - - User clicks share or pastes your Mini App URL into a social feed (Base App, Farcaster). - - - - The platform makes a request to your URL and reads the `` tags in your HTML to understand how to display your app. - - - - Platform transforms your metadata into a rich visual embed with image, title, description, and interactive button. - - - - Your Mini App appears as an attractive, clickable card that users can launch directly from their feed. - - - -### Metadata Structure - -Your metadata consists of specific HTML meta tags that define each part of the embed: - -```html index.html - -``` - -Each piece of metadata directly corresponds to a visual element in the embed: - -- `imageUrl` → The main visual that appears in the embed -- `button.title` → Text on the call-to-action button -- `action.name` → App name displayed in the embed -- `action.url` → Where users go when they click the embed - -### Embed Appearance in Feeds - - -Mini app feed - - -### Manifest vs Embed Metadata - -Your Mini App uses two types of metadata: - -#### Manifest file - -Purpose: App registration and discovery - -Located at `/.well-known/farcaster.json`, this file contains your app's basic information for Base App's directory. - - -Mini Apps require a complete manifest. Read the [manifest requirements](/mini-apps/features/manifest#example-manifest). - - -#### Embed metadata - -Purpose: Embed generation when shared - -Located in your HTML `` tags, this metadata creates the rich embeds when users share your app. - -```html index.html - -``` - -This controls how your embeds appear in social feeds. - -### Best Practices for Metadata - -- Image optimization: Use 3:2 aspect ratio -- Clear value proposition in button and text -- Visual consistency with product UI -- Fast loading for metadata endpoints -- Validate across platforms pre‑launch - -## Sharing - -### Adding Share Functionality - -Prompt users to share during key accomplishment moments using MiniKit’s compose hook. - -```ts ComposeCastButton.tsx -import { useComposeCast } from '@coinbase/onchainkit/minikit'; - -export default function ComposeCastButton() { - const { composeCast } = useComposeCast(); - - const handleCompose = () => { - composeCast({ - text: 'Just minted an awesome NFT using @coinbase OnchainKit! ', - }); - }; - - const handleComposeWithEmbed = () => { - composeCast({ - text: 'Check out this amazing Mini App!', - embeds: ['https://your-mini-app-url.com'], - }); - }; - - return ( -
- - -
- ); -} -``` - - -Strategic sharing moments: - -- After completing a quiz -- After minting an NFT -- After beating a challenge -- After reaching a milestone - - -### From the Base App UI - -Users can also share directly from your app's detail view in the Base app through the built‑in share functionality. - - - Share button in Base app - - -## Embed Types - -### Static embeds - -Use a single, unchanging image and text for all shares. Best for consistency and speed. - -### Dynamic embeds - -Generate metadata per user or event for personalization and FOMO. Ensure fast response (< 5s) and caching strategy. - -## Implementation - -### With MiniKit (Next.js) - -```ts layout.tsx -export async function generateMetadata(): Promise { - const URL = process.env.NEXT_PUBLIC_URL; - return { - title: process.env.NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAME, - description: "Your Mini App description here", - other: { - "fc:frame": JSON.stringify({ - version: "next", - imageUrl: process.env.NEXT_PUBLIC_APP_HERO_IMAGE, - button: { - title: `Launch ${process.env.NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAME}`, - action: { - type: "launch_frame", - name: process.env.NEXT_PUBLIC_ONCHAINKIT_PROJECT_NAME, - url: URL, - splashImageUrl: process.env.NEXT_PUBLIC_SPLASH_IMAGE, - splashBackgroundColor: process.env.NEXT_PUBLIC_SPLASH_BACKGROUND_COLOR, - }, - }, - }), - }, - }; -} -``` - -### Without MiniKit - -```html index.html - -``` - -## Debugging - -### Tools - - - Test how your app will appear in the Base app by validating your manifest, embeds, and account association - - -### Common issues - - - -Check image dimensions, required `fc:frame`, JSON validity, and URL accessibility. - - -Review cache headers, repost to refresh, wait ~10–15 minutes for caches. - - -Optimize image generation, pre‑generate, use serverless, compress assets. - - - - -Set `Cache-Control` carefully: long enough for performance (300–600s), short enough for quick updates. - - -## Next Steps - - - - - - - - -Continue with: - -- [Search and Discovery](/mini-apps/troubleshooting/how-search-works) -- [Manifest](/mini-apps/core-concepts/manifest) - - - From 9db8bc9df1d9523903f8d2e9117a741aee0b9024 Mon Sep 17 00:00:00 2001 From: sohey Date: Mon, 27 Oct 2025 13:50:37 +0100 Subject: [PATCH 2/9] added embed metadata --- docs/mini-apps/technical-guides/dynamic-embeds.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index 17b83ba5..f92285b3 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -19,8 +19,8 @@ This guide uses Next.js App Router with ImageResponse for implementation. The pa ## Implementation - -Pass the user's FID to your image endpoint via URL parameters. + +Create a page that passes the user's FID to your image endpoint via URL parameters. ```tsx app/dynamic-image-example/[id]/page.tsx import { Metadata } from "next"; @@ -36,7 +36,7 @@ export async function generateMetadata({ const imageUrl = `${appUrl}/api/og/example/${id}`; - const frame = { + const miniapp = { version: "next", imageUrl: imageUrl, button: { From 8e0de22e66baac8c477bd0c8ae26ce146cb11d62 Mon Sep 17 00:00:00 2001 From: sohey Date: Mon, 27 Oct 2025 18:21:01 +0100 Subject: [PATCH 3/9] added embed metadata --- .../technical-guides/dynamic-embeds.mdx | 235 ++++++++++-------- 1 file changed, 137 insertions(+), 98 deletions(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index f92285b3..8d5fe779 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -9,7 +9,7 @@ Dynamic images are the first thing users see when they encounter your mini app i How embed data is rendered -When users share your mini app `URL`, the Base app requests your page, reads the fc:miniapp metadata, and fetches the `OGImageUrl`. You can serve either a static file (same image for everyone) or a dynamic endpoint that generates unique images on-demand based on URL parameters. +When users share your mini app `URL`, the Base app requests your page, reads the fc:miniapp metadata, and fetches the `imageUrl`. You can serve either a static file (same image for everyone) or a dynamic endpoint that generates unique images on-demand based on URL parameters. @@ -18,136 +18,175 @@ This guide uses Next.js App Router with ImageResponse for implementation. The pa ## Implementation - - -Create a page that passes the user's FID to your image endpoint via URL parameters. - -```tsx app/dynamic-image-example/[id]/page.tsx -import { Metadata } from "next"; - -const appUrl = process.env.NEXT_PUBLIC_URL; - -export async function generateMetadata({ - params, -}: { - params: Promise<{ id: string }>; -}): Promise { - const { id } = await params; - - const imageUrl = `${appUrl}/api/og/example/${id}`; - - const miniapp = { - version: "next", - imageUrl: imageUrl, - button: { - title: "Launch App", - action: { - type: "launch_frame", - name: "Mini App", - url: appUrl, - splashImageUrl: `${appUrl}/images/splash.png`, - splashBackgroundColor: "#f7f7f7", - }, - }, - }; - - return { - title: "Mini App", - other: { - "fc:frame": JSON.stringify(frame), - }, - }; -} - -export default function DynamicImagePage() { - return
Your app content
; -} -``` - -The `id` parameter becomes part of the image URL: `/api/og/example/123` -
+This guide shows how to create shareable links with dynamic embed images. Users click a share button, which opens a compose window with their personalized link. When shared, the embed displays a unique image with their username. - -Create an API route that reads the FID and generates a unique image. + + +Build an API route that generates images based on the username parameter. -```tsx app/api/og/example/[id]/route.tsx +```tsx app/api/og/[username]/route.tsx import { ImageResponse } from "next/og"; export const dynamic = "force-dynamic"; -const size = { - width: 600, - height: 400, -}; - export async function GET( request: Request, - { params }: { params: Promise<{ id: string }> } + { params }: { params: Promise<{ username: string }> } ) { - const { id } = await params; + const { username } = await params; return new ImageResponse( (
-
- User FID: {id} + style={{ + backgroundColor: 'black', + backgroundSize: '150px 150px', + height: '100%', + width: '100%', + display: 'flex', + color: 'white', + textAlign: 'center', + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'column', + flexWrap: 'nowrap', + }} + > + Hello {username}
-
), { - ...size, + width: 1200, + height: 630, } ); } ``` -Each unique FID generates a different image. +This endpoint generates a unique image for each username: `/api/og/alice`, `/api/og/bob`, etc. + + + `
` elements must have `display: "flex"` or `display: "none"`. If you see a 500 error when accessing `/share/[username]`, check your ImageResponse JSX structure. + - -Verify your dynamic image generates correctly. + +Build a page route that uses the username to generate `fc:miniapp` metadata pointing to your image endpoint. -```bash -curl http://localhost:3000/api/og/example/123 > test.png -open test.png -``` +```tsx app/share/[username]/page.tsx +import { minikitConfig } from "../../../minikit.config"; +import { Metadata } from "next"; -Each different FID produces a unique image. +export async function generateMetadata( + { params }: { params: Promise<{ username: string }> } +): Promise { + try { + const { username } = await params; + + return { + title: minikitConfig.miniapp.name, + description: minikitConfig.miniapp.description, + other: { + "fc:miniapp": JSON.stringify({ + version: minikitConfig.miniapp.version, + imageUrl: `${minikitConfig.miniapp.homeUrl}/api/og/${username}`, + button: { + title: `Join the ${minikitConfig.miniapp.name} Waitlist`, + action: { + name: `Launch ${minikitConfig.miniapp.name}`, + type: "launch_frame", + url: `${minikitConfig.miniapp.homeUrl}`, + }, + }, + }), + }, + }; + } catch (e) { + const errorMessage = e instanceof Error ? e.message : 'Unknown error'; + console.log(JSON.stringify({ + timestamp: new Date().toISOString(), + level: 'error', + message: 'Failed to generate metadata', + error: errorMessage + })); + + return { + title: minikitConfig.miniapp.name, + description: minikitConfig.miniapp.description, + }; + } +} + +export default async function SharePage( + { params }: { params: Promise<{ username: string }> } +) { + const { username } = await params; + + return ( +
+

Share Page - {username}

+
+ ); +} +``` +When someone visits `/share/alice`, the metadata points to `/api/og/alice` for the embed image.
- -## Troubleshooting + +Create a button that opens Farcaster's compose window with the user's personalized share link. -**Gray images in embeds** -- Generation takes >2s. Use cached data sources instead of database queries. -- Verify image dimensions are 3:2 ratio (1200x800px). +```tsx app/page.tsx +import { useMiniKit, useComposeCast } from "@coinbase/onchainkit/minikit"; +import { minikitConfig } from "./minikit.config"; -**Stale data showing** -- Decrease `max-age` to match your data update frequency. -- Add version parameter to URL: `?v=2` to force refresh. +export default function HomePage() { + const { context } = useMiniKit(); + const { composeCast } = useComposeCast(); -**High function costs** -- Increase `max-age` to reduce regeneration frequency. -- Verify `Cache-Control` header includes `public` directive. + const handleShareApp = () => { + const userName = context?.user?.displayName || 'anonymous'; + composeCast({ + text: `Check out ${minikitConfig.miniapp.name}!`, + embeds: [`${window.location.origin}/share/${userName}`] + }); + }; -**Embed not displaying** -- Check metadata exists: `curl https://your-domain.com/page | grep "fc:miniapp"` -- Validate with debugger: https://warpcast.com/~/developers/frames/debug + return ( +
+ +
+ ); +} +``` + +When clicked the button opens the compose window with `/share/alice` as the embed. The embed displays the dynamic image from `/api/og/alice`. +
+ + +Verify the complete sharing flow works. + +```bash +# Start your app +npm run dev +# Test the image endpoint directly +curl http://localhost:3000/api/og/testuser > test.png +open test.png -- [Search and Discovery](/mini-apps/troubleshooting/how-search-works) -- [Manifest](/mini-apps/core-concepts/manifest) +# Visit the share page to verify metadata +curl http://localhost:3000/share/testuser | grep "fc:frame" +``` +Click the share button in your app to test the full experience. + + +## Related Concepts + + + Troubleshooting tips for embeds not displaying. + + From 5433649e213d983f9681de262b396fbcf73cbf4c Mon Sep 17 00:00:00 2001 From: sohey Date: Mon, 27 Oct 2025 18:23:37 +0100 Subject: [PATCH 4/9] review based on content guidelines --- .../technical-guides/dynamic-embeds.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index 8d5fe779..eb3c11c8 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -7,7 +7,7 @@ Dynamic images are the first thing users see when they encounter your mini app i - How embed data is rendered + Diagram showing the flow from mini app URL to metadata reading to image generation and final embed rendering in the Base app When users share your mini app `URL`, the Base app requests your page, reads the fc:miniapp metadata, and fetches the `imageUrl`. You can serve either a static file (same image for everyone) or a dynamic endpoint that generates unique images on-demand based on URL parameters. @@ -24,7 +24,7 @@ This guide shows how to create shareable links with dynamic embed images. Users Build an API route that generates images based on the username parameter. -```tsx app/api/og/[username]/route.tsx +```tsx lines expandable wrap app/api/og/[username]/route.tsx import { ImageResponse } from "next/og"; export const dynamic = "force-dynamic"; @@ -73,7 +73,7 @@ This endpoint generates a unique image for each username: `/api/og/alice`, `/api Build a page route that uses the username to generate `fc:miniapp` metadata pointing to your image endpoint. -```tsx app/share/[username]/page.tsx +```tsx lines expandable wrap app/share/[username]/page.tsx import { minikitConfig } from "../../../minikit.config"; import { Metadata } from "next"; @@ -135,7 +135,7 @@ When someone visits `/share/alice`, the metadata points to `/api/og/alice` for t Create a button that opens Farcaster's compose window with the user's personalized share link. -```tsx app/page.tsx +```tsx lines expandable wrap app/page.tsx import { useMiniKit, useComposeCast } from "@coinbase/onchainkit/minikit"; import { minikitConfig } from "./minikit.config"; @@ -161,13 +161,13 @@ export default function HomePage() { } ``` -When clicked the button opens the compose window with `/share/alice` as the embed. The embed displays the dynamic image from `/api/og/alice`. +When you click the button, it opens the compose window with `/share/alice` as the embed. The embed displays the dynamic image from `/api/og/alice`. Verify the complete sharing flow works. -```bash +```bash lines wrap # Start your app npm run dev @@ -176,10 +176,10 @@ curl http://localhost:3000/api/og/testuser > test.png open test.png # Visit the share page to verify metadata -curl http://localhost:3000/share/testuser | grep "fc:frame" +curl http://localhost:3000/share/testuser | grep "fc:miniapp" ``` -Click the share button in your app to test the full experience. +Click the share button in your app to test the full experience. You should see the compose window open with your personalized share link, and the embed should display your custom generated image. From f3819261182d68da48df18dbf63e6edb2a15286b Mon Sep 17 00:00:00 2001 From: sohey Date: Mon, 27 Oct 2025 18:27:40 +0100 Subject: [PATCH 5/9] changed link to vercel og --- docs/mini-apps/technical-guides/dynamic-embeds.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index eb3c11c8..838dc616 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -13,7 +13,7 @@ When users share your mini app `URL`, the Base app requests your page, reads the -This guide uses Next.js App Router with ImageResponse for implementation. The patterns apply to any framework with server-side rendering. +This guide uses the [Vercel OG Image library](https://vercel.com/docs/og-image-generation) with the Next.js App Router for dynamic image generation. The patterns apply to any framework with server-side rendering. ## Implementation From 469b2215f821b949347a8aeaab5e68fb48a06e70 Mon Sep 17 00:00:00 2001 From: sohey Date: Tue, 28 Oct 2025 17:07:23 +0100 Subject: [PATCH 6/9] call out install next og --- docs/mini-apps/technical-guides/dynamic-embeds.mdx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index 838dc616..cc312821 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -1,6 +1,6 @@ --- -title: Dynamic OG Image Generation -description: Generate real-time preview images for Base mini app embeds +title: Generate Dynamic Embed Images +description: Create viral loops by turning every user interaction into dynamic, shareable content directly in the feed. --- Dynamic images are the first thing users see when they encounter your mini app in their feed. Each share can display unique, contextual content tailored to drive engagement. @@ -16,6 +16,14 @@ When users share your mini app `URL`, the Base app requests your page, reads the This guide uses the [Vercel OG Image library](https://vercel.com/docs/og-image-generation) with the Next.js App Router for dynamic image generation. The patterns apply to any framework with server-side rendering. +## Prerequisites + +Install `@vercel/og` by running the following command inside your project directory. This isn't required for Next.js App Router projects, as the package is already included: + +```bash +npm install @vercel/og +``` + ## Implementation This guide shows how to create shareable links with dynamic embed images. Users click a share button, which opens a compose window with their personalized link. When shared, the embed displays a unique image with their username. From 5539d5c9bf51c181abd1859d5fc06952acb03a3c Mon Sep 17 00:00:00 2001 From: sohey Date: Tue, 28 Oct 2025 17:19:55 +0100 Subject: [PATCH 7/9] changed sentence --- docs/mini-apps/technical-guides/dynamic-embeds.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index cc312821..7f12605a 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -3,7 +3,7 @@ title: Generate Dynamic Embed Images description: Create viral loops by turning every user interaction into dynamic, shareable content directly in the feed. --- -Dynamic images are the first thing users see when they encounter your mini app in their feed. Each share can display unique, contextual content tailored to drive engagement. +Embeds are the first thing users see when they encounter your mini app in their feed. Each share can display unique, contextual content tailored to drive engagement. @@ -143,7 +143,7 @@ When someone visits `/share/alice`, the metadata points to `/api/og/alice` for t Create a button that opens Farcaster's compose window with the user's personalized share link. -```tsx lines expandable wrap app/page.tsx +```tsx lines expandable wrap app/page.tsx highlight={6, 9-15} import { useMiniKit, useComposeCast } from "@coinbase/onchainkit/minikit"; import { minikitConfig } from "./minikit.config"; @@ -151,6 +151,7 @@ export default function HomePage() { const { context } = useMiniKit(); const { composeCast } = useComposeCast(); + const handleShareApp = () => { const userName = context?.user?.displayName || 'anonymous'; composeCast({ From 466013768b3df77225a0c8cda046c6c4e3e0faa8 Mon Sep 17 00:00:00 2001 From: sohey Date: Tue, 28 Oct 2025 18:04:41 +0100 Subject: [PATCH 8/9] changed sentence --- docs/mini-apps/technical-guides/dynamic-embeds.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index 7f12605a..42e6eb9e 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -13,7 +13,7 @@ When users share your mini app `URL`, the Base app requests your page, reads the -This guide uses the [Vercel OG Image library](https://vercel.com/docs/og-image-generation) with the Next.js App Router for dynamic image generation. The patterns apply to any framework with server-side rendering. +This guide uses Minikit but the principles apply to any framework with server-side rendering. ## Prerequisites From 5d530bc251f179fe0279ac2aa25c23f31e3c24a7 Mon Sep 17 00:00:00 2001 From: sohey Date: Wed, 29 Oct 2025 18:59:54 +0100 Subject: [PATCH 9/9] added extra step --- docs/mini-apps/technical-guides/dynamic-embeds.mdx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/mini-apps/technical-guides/dynamic-embeds.mdx b/docs/mini-apps/technical-guides/dynamic-embeds.mdx index 42e6eb9e..539f4fef 100644 --- a/docs/mini-apps/technical-guides/dynamic-embeds.mdx +++ b/docs/mini-apps/technical-guides/dynamic-embeds.mdx @@ -16,19 +16,18 @@ When users share your mini app `URL`, the Base app requests your page, reads the This guide uses Minikit but the principles apply to any framework with server-side rendering. -## Prerequisites +## Implementation + +This guide shows how to create shareable links with dynamic embed images. Users click a share button, which opens a compose window with their personalized link. When shared, the embed displays a unique image with their username. + + Install `@vercel/og` by running the following command inside your project directory. This isn't required for Next.js App Router projects, as the package is already included: ```bash npm install @vercel/og ``` - -## Implementation - -This guide shows how to create shareable links with dynamic embed images. Users click a share button, which opens a compose window with their personalized link. When shared, the embed displays a unique image with their username. - - + Build an API route that generates images based on the username parameter.