From 162e0ccc9d1c8165b5f435e6db0ad2fe0da4ff5b Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Tue, 24 Mar 2026 11:27:09 +0000 Subject: [PATCH] [#490] Add native Farcaster miniapp install + notification modal After sdk.actions.ready(), check context.client.added and trigger sdk.actions.addMiniApp() for users who haven't added PlotLink yet. The native Farcaster modal handles install + notification permission. Only fires on platform === 'farcaster', no re-prompting for users who already added or dismissed. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/FarcasterMiniApp.tsx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/components/FarcasterMiniApp.tsx b/src/components/FarcasterMiniApp.tsx index 3fb6554c..62edbc0e 100644 --- a/src/components/FarcasterMiniApp.tsx +++ b/src/components/FarcasterMiniApp.tsx @@ -4,8 +4,12 @@ import { useEffect } from "react"; import { usePlatformDetection } from "../hooks/usePlatformDetection"; /** - * Calls `sdk.actions.ready()` to dismiss the splash screen — only in Farcaster clients. - * After Base App migration (April 2026), Base App operates as standard web app. + * Farcaster Mini App lifecycle — only runs in Farcaster clients. + * + * 1. Calls `sdk.actions.ready()` to dismiss the splash screen. + * 2. If the user hasn't added the app yet, triggers `sdk.actions.addMiniApp()` + * which shows the native Farcaster modal for install + notification permission. + * The SDK/client handles "already added" state — no re-prompting. * * Renders nothing — mount once near the root of the component tree. */ @@ -19,7 +23,20 @@ export function FarcasterMiniApp() { import("@farcaster/miniapp-sdk").then(async ({ sdk }) => { if (cancelled) return; + + // Dismiss splash screen sdk.actions.ready(); + + // Check if user has already added the miniapp + const context = await sdk.context; + if (cancelled || !context?.client) return; + + if (!context.client.added) { + // Trigger native add/notification modal — SDK handles dismissal gracefully + sdk.actions.addMiniApp().catch(() => { + // User dismissed or SDK error — no action needed + }); + } }).catch(() => { // Not in a Farcaster context — silently ignore });