From 95b73871ffba86946155cac69755aa1b668e7a97 Mon Sep 17 00:00:00 2001 From: Patrick Hughes Date: Thu, 16 Oct 2025 20:35:04 -0500 Subject: [PATCH 1/4] remove technical reference folder for minikit --- .../core-concepts/authentication.mdx | 2 +- docs/mini-apps/core-concepts/navigation.mdx | 6 +- docs/mini-apps/growth/optimize-onboarding.mdx | 6 +- docs/mini-apps/llms-full.txt | 16 +- docs/mini-apps/llms.txt | 4 +- .../sharing-and-social-graph.mdx | 4 +- .../minikit/hooks/useAddFrame.mdx | 227 ---------- .../minikit/hooks/useAuthenticate.mdx | 144 ------ .../minikit/hooks/useClose.mdx | 194 --------- .../minikit/hooks/useComposeCast.mdx | 261 ----------- .../minikit/hooks/useMiniKit.mdx | 171 -------- .../minikit/hooks/useNotification.mdx | 409 ------------------ .../minikit/hooks/useOpenUrl.mdx | 77 ---- .../minikit/hooks/usePrimaryButton.mdx | 242 ----------- .../minikit/hooks/useViewCast.mdx | 312 ------------- .../minikit/hooks/useViewProfile.mdx | 251 ----------- .../technical-reference/minikit/overview.mdx | 94 ---- .../minikit/provider-and-initialization.mdx | 111 ----- 18 files changed, 19 insertions(+), 2512 deletions(-) delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useAddFrame.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useAuthenticate.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useClose.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useComposeCast.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useMiniKit.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useNotification.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useOpenUrl.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/usePrimaryButton.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useViewCast.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/hooks/useViewProfile.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/overview.mdx delete mode 100644 docs/mini-apps/technical-reference/minikit/provider-and-initialization.mdx diff --git a/docs/mini-apps/core-concepts/authentication.mdx b/docs/mini-apps/core-concepts/authentication.mdx index 6857d3cc..cd56072d 100644 --- a/docs/mini-apps/core-concepts/authentication.mdx +++ b/docs/mini-apps/core-concepts/authentication.mdx @@ -149,7 +149,7 @@ Your mini app's domain - + use Minikit's useAuthenticate hook to authenticate users. diff --git a/docs/mini-apps/core-concepts/navigation.mdx b/docs/mini-apps/core-concepts/navigation.mdx index 895d2b02..452965d5 100644 --- a/docs/mini-apps/core-concepts/navigation.mdx +++ b/docs/mini-apps/core-concepts/navigation.mdx @@ -101,7 +101,7 @@ composeCast({ - Use [`useOpenUrl()`](/mini-apps/technical-reference/minikit/hooks/useOpenUrl) to safely open external websites in the client's in-app browser: + Use [`useOpenUrl()`](/onchainkit/latest/components/minikit/hooks/useOpenUrl) to safely open external websites in the client's in-app browser: ```tsx components/ExternalLinks.tsx highlight={8 -10} import { useOpenUrl } from '@coinbase/onchainkit/minikit'; @@ -153,7 +153,7 @@ composeCast({ ``` - Use [`useComposeCast()`](/mini-apps/technical-reference/minikit/hooks/useComposeCast) to open the native composer with prefilled content: + Use [`useComposeCast()`](/onchainkit/latest/components/minikit/hooks/useComposeCast) to open the native composer with prefilled content: ```tsx components/ShareCast.tsx highlight={8-13} import { useComposeCast } from '@coinbase/onchainkit/minikit'; @@ -198,7 +198,7 @@ composeCast({ - Use [`useViewCast()`](/mini-apps/technical-reference/minikit/hooks/useViewCast) to open a specific cast by its hash: + Use [`useViewCast()`](/onchainkit/latest/components/minikit/hooks/useViewCast) to open a specific cast by its hash: ```tsx components/ViewCastButton.tsx highlight={4,7-9} import { useViewCast } from '@coinbase/onchainkit/minikit'; diff --git a/docs/mini-apps/growth/optimize-onboarding.mdx b/docs/mini-apps/growth/optimize-onboarding.mdx index b3b03a30..8fa43b69 100644 --- a/docs/mini-apps/growth/optimize-onboarding.mdx +++ b/docs/mini-apps/growth/optimize-onboarding.mdx @@ -20,7 +20,7 @@ Deliver value instantly and avoid blocking actions. - Show immediate value (demo content, sample state, or read-only mode) -- Personalize instantly with [`context`](/mini-apps/technical-reference/minikit/provider-and-initialization) of the user's profile to instantly personalize +- Personalize instantly with [`context`](/onchainkit/latest/components/minikit/provider-and-initialization) of the user's profile to instantly personalize - Display one clear CTA that leads to a meaningful action (e.g. "Post a message", "Buy a token", "Follow a user") @@ -108,8 +108,8 @@ Learn how to implement them with [SDK actions](/mini-apps/features/links). - - + + diff --git a/docs/mini-apps/llms-full.txt b/docs/mini-apps/llms-full.txt index 07ac91d2..4026123e 100644 --- a/docs/mini-apps/llms-full.txt +++ b/docs/mini-apps/llms-full.txt @@ -59,9 +59,9 @@ export function Providers(props: { children: React.ReactNode }) { - [Base App Compatibility](https://docs.base.org/mini-apps/troubleshooting/base-app-compatibility.md) — Client behavior ### Technical Reference -- [MiniKit Overview](https://docs.base.org/mini-apps/technical-reference/minikit/overview.md) — Overview -- [Provider & Initialization](https://docs.base.org/mini-apps/technical-reference/minikit/provider-and-initialization.md) — Provider -- [Hooks](https://docs.base.org/mini-apps/technical-reference/minikit/hooks/useMiniKit.md) — Hooks +- [MiniKit Overview](https://docs.base.org/onchainkit/latest/components/minikit/overview.md) — Overview +- [Provider & Initialization](https://docs.base.org/onchainkit/latest/components/minikit/provider-and-initialization.md) — Provider +- [Hooks](https://docs.base.org/onchainkit/latest/components/minikit/hooks/useMiniKit.md) — Hooks ## Quickstart (excerpts) @@ -128,7 +128,7 @@ Modes summary (from Authentication): Hook reference: - useAuthenticate — Returns verified user from SIWF or wallet auth. Use alongside `useMiniKit` context. - - Source: `https://docs.base.org/mini-apps/technical-reference/minikit/hooks/useAuthenticate.md` + - Source: `https://docs.base.org/onchainkit/latest/components/minikit/hooks/useAuthenticate.md` Example (hook usage): @@ -171,9 +171,9 @@ Prompt timing guidelines: ## API and Schemas (pruned) - MiniKit Provider and initialization props - - Source: `https://docs.base.org/mini-apps/technical-reference/minikit/provider-and-initialization.md` + - Source: `https://docs.base.org/onchainkit/latest/components/minikit/provider-and-initialization.md` - `useMiniKit` hook: access frame context, user, and client capabilities - - Source: `https://docs.base.org/mini-apps/technical-reference/minikit/hooks/useMiniKit.md` + - Source: `https://docs.base.org/onchainkit/latest/components/minikit/hooks/useMiniKit.md` Example manifest fields (conceptual): @@ -221,7 +221,7 @@ Example: Wire providers for OnchainKit + MiniKit Sources: - `https://docs.base.org/mini-apps/design-ux/onchainkit.md` -- `https://docs.base.org/mini-apps/technical-reference/minikit/provider-and-initialization.md` +- `https://docs.base.org/onchainkit/latest/components/minikit/provider-and-initialization.md` ```tsx import { OnchainKitProvider } from '@coinbase/onchainkit' @@ -238,7 +238,7 @@ export function Providers(props: { children: React.ReactNode }) { Example: Use `useMiniKit` to access client context -Source: `https://docs.base.org/mini-apps/technical-reference/minikit/hooks/useMiniKit.md` +Source: `https://docs.base.org/onchainkit/latest/components/minikit/hooks/useMiniKit.md` ```tsx import { useMiniKit } from '@coinbase/minikit' diff --git a/docs/mini-apps/llms.txt b/docs/mini-apps/llms.txt index 852e4b4d..1de2d10c 100644 --- a/docs/mini-apps/llms.txt +++ b/docs/mini-apps/llms.txt @@ -29,8 +29,8 @@ - [Base App Compatibility](https://docs.base.org/mini-apps/troubleshooting/base-app-compatibility.md) — Base App client-specific behaviors for issues where an app works in the Farcaster client but not Base App ## Technical Reference -- [MiniKit Overview](https://docs.base.org/mini-apps/technical-reference/minikit/overview.md) — Architecture, provider, CLI, and hooks -- [Hooks: useMiniKit](https://docs.base.org/mini-apps/technical-reference/minikit/hooks/useMiniKit.md) — Access frame context and client features +- [MiniKit Overview](https://docs.base.org/onchainkit/latest/components/minikit/overview.md) — Architecture, provider, CLI, and hooks +- [Hooks: useMiniKit](https://docs.base.org/onchainkit/latest/components/minikit/hooks/useMiniKit.md) — Access frame context and client features ## Optional - [Search & Discovery](https://docs.base.org/mini-apps/features/search-and-discovery.md) — Indexing and ranking signals in Base App diff --git a/docs/mini-apps/technical-guides/sharing-and-social-graph.mdx b/docs/mini-apps/technical-guides/sharing-and-social-graph.mdx index bea884e6..f24ea535 100644 --- a/docs/mini-apps/technical-guides/sharing-and-social-graph.mdx +++ b/docs/mini-apps/technical-guides/sharing-and-social-graph.mdx @@ -42,8 +42,8 @@ Strategic sharing moments include: post‑achievement, post‑mint, after beatin Link users into casts and profiles directly from your app via MiniKit hooks. - - + + ## Best Practices diff --git a/docs/mini-apps/technical-reference/minikit/hooks/useAddFrame.mdx b/docs/mini-apps/technical-reference/minikit/hooks/useAddFrame.mdx deleted file mode 100644 index 0aa84401..00000000 --- a/docs/mini-apps/technical-reference/minikit/hooks/useAddFrame.mdx +++ /dev/null @@ -1,227 +0,0 @@ ---- -title: useAddFrame (coming soon) -description: Allow users to save your Mini App to their collection (Coming Soon) ---- - -Defined in [@coinbase/onchainkit](https://github.com/coinbase/onchainkit) - - -The Add Frame feature is not yet available in Base App but is coming soon. This documentation describes the upcoming API that will be available when the feature is fully deployed. - - - -Enables users to save your Mini App to their personal collection for quick access. Returns notification credentials when successful, enabling future push notifications to re-engage the user. - - -## Returns - - -Function that triggers the add frame flow. Returns a promise that resolves when the user completes the action. - - - -The URL that was saved to the user's collection. This should match your Mini App's manifest URL. - - - -Notification token for this user and Mini App combination. Save this to your database to send push notifications later. - - - - - -```tsx components/SaveButton.tsx -import { useAddFrame } from '@coinbase/onchainkit/minikit'; -import { useState } from 'react'; - -export default function SaveButton() { - const addFrame = useAddFrame(); - const [isAdding, setIsAdding] = useState(false); - - const handleAddFrame = async () => { - setIsAdding(true); - try { - const result = await addFrame(); - if (result) { - console.log('Frame saved:', result.url); - console.log('Notification token:', result.token); - - // Save to your database for future notifications - await saveNotificationToken(result.token, result.url); - - alert('Mini App saved successfully! 🎉'); - } else { - console.log('User cancelled or frame already saved'); - } - } catch (error) { - console.error('Failed to save frame:', error); - } finally { - setIsAdding(false); - } - }; - - return ( - - ); -} - -async function saveNotificationToken(token: string, url: string) { - await fetch('/api/notification-tokens', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ token, url }) - }); -} -``` - -```tsx components/SmartSaveButton.tsx -import { useAddFrame, useMiniKit } from '@coinbase/onchainkit/minikit'; - -export default function SmartSaveButton() { - const addFrame = useAddFrame(); - const { context } = useMiniKit(); - - // Don't show save button if already saved - if (context.client.added) { - return
✅ Already saved to your collection
; - } - - const handleSave = async () => { - const result = await addFrame(); - if (result) { - // Save with user context for analytics - await fetch('/api/analytics', { - method: 'POST', - body: JSON.stringify({ - event: 'frame_saved', - userFid: context.user.fid, - url: result.url, - token: result.token - }) - }); - } - }; - - return ( - - ); -} -``` - -```tsx components/GameCompletion.tsx -import { useAddFrame } from '@coinbase/onchainkit/minikit'; -import { useEffect, useState } from 'react'; - -export default function GameCompletion() { - const addFrame = useAddFrame(); - const [showSavePrompt, setShowSavePrompt] = useState(false); - - // Show save prompt after user achieves something - const handleGameWin = () => { - setShowSavePrompt(true); - }; - - const handleSave = async () => { - const result = await addFrame(); - if (result) { - // User saved after achievement - high engagement signal - analytics.track('post_achievement_save', { - achievement: 'game_completed', - token: result.token - }); - } - setShowSavePrompt(false); - }; - - return ( -
- {showSavePrompt && ( -
-

🎉 Congratulations!

-

Save this game to play again anytime

- - -
- )} -
- ); -} -``` -
- -## Usage Patterns - -### Database Storage -Always save the notification token to your database for future use: - -```typescript pages/api/notification-tokens.ts -// Example API route for storing tokens -// pages/api/notification-tokens.ts -export default async function handler(req, res) { - if (req.method === 'POST') { - const { token, url, userFid } = req.body; - - await db.notificationTokens.create({ - data: { - token, - url, - userFid, - createdAt: new Date() - } - }); - - res.status(200).json({ success: true }); - } -} -``` - -### Strategic Timing -Prompt users to save at high-value moments: - -- ✅ **After achievements**: Completing a game, reaching a milestone -- ✅ **After successful transactions**: Minting an NFT, making a purchase -- ✅ **During onboarding**: After showing app value -- ❌ **Immediately on load**: Before demonstrating value -- ❌ **Multiple times**: Respect user's previous decision - -### Error Handling -Handle various outcomes gracefully: - -```tsx -const handleAddFrame = async () => { - try { - const result = await addFrame(); - - if (result === null) { - // User cancelled or already saved - console.log('No action taken'); - } else { - // Successfully saved - console.log('Saved with token:', result.token); - } - } catch (error) { - // Network error or other issue - console.error('Save failed:', error); - showErrorMessage('Failed to save. Please try again.'); - } -}; -``` - - -The notification token is unique per user and Mini App combination. Store it securely in your database and never expose it in client-side code. Tokens are required for sending push notifications when that feature becomes available. - - - -Users can only save each Mini App once. Subsequent calls to `addFrame()` for the same user and app will return `null`. Use `context.client.added` from `useMiniKit` to check if the user has already saved your app. - - - diff --git a/docs/mini-apps/technical-reference/minikit/hooks/useAuthenticate.mdx b/docs/mini-apps/technical-reference/minikit/hooks/useAuthenticate.mdx deleted file mode 100644 index 9b646949..00000000 --- a/docs/mini-apps/technical-reference/minikit/hooks/useAuthenticate.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: useAuthenticate -description: Cryptographically authenticate users with Sign In with Farcaster ---- - -Defined in [@coinbase/onchainkit](https://github.com/coinbase/onchainkit) - - -Provides cryptographically secure user authentication using Sign In with Farcaster (SIWF). Returns verified user identity and signature for secure operations. - - -## Returns - - -Authenticated user object with verified identity, or null if not authenticated. - - - -Verified Farcaster ID of the authenticated user. - - - -Cryptographic signature proving user identity. - - - -The signed message used for authentication. - - - - - -Function to trigger the authentication flow. Returns verified user data on success. - - - -```tsx components/AuthButton.tsx -import { useAuthenticate } from '@coinbase/onchainkit/minikit'; -import { useState } from 'react'; - -export default function AuthButton() { - const { user, authenticate } = useAuthenticate(); - const [isAuthenticating, setIsAuthenticating] = useState(false); - - const handleAuth = async () => { - setIsAuthenticating(true); - try { - const authenticatedUser = await authenticate(); - if (authenticatedUser) { - console.log('Authenticated user:', authenticatedUser.fid); - // Save to your backend - await saveUserSession(authenticatedUser); - } - } catch (error) { - console.error('Authentication failed:', error); - } finally { - setIsAuthenticating(false); - } - }; - - if (user) { - return ( -
-

✅ Authenticated as FID: {user.fid}

- -
- ); - } - - return ( - - ); -} -``` - -```tsx components/ProtectedFeature.tsx -import { useAuthenticate } from '@coinbase/onchainkit/minikit'; - -export default function ProtectedFeature() { - const { user, authenticate } = useAuthenticate(); - - if (!user) { - return ( -
-

Authentication Required

-

Please sign in to access this feature

- -
- ); - } - - return ( -
-

Welcome, {user.fid}!

-

This is a protected feature only available to authenticated users.

-
- ); -} -``` -
- - -### Context vs Authentication -Use the right tool for the job: - -```tsx components/SecurityExample.tsx -import { useAuthenticate, useMiniKit } from '@coinbase/onchainkit/minikit'; - -export default function SecurityExample() { - const { user } = useAuthenticate(); // For security - const { context } = useMiniKit(); // For UX - - return ( -
- {/* Safe: UX personalization with context */} - {context.user.fid && ( -

Hi there, user {context.user.fid}!

- )} - - {/* Safe: Security with authentication */} - {user && ( - - )} -
- ); -} -``` - - - - -`useAuthenticate` provides cryptographic proof of user identity. Always verify signatures server-side for security-critical operations. Use `useMiniKit` context only for UX hints and analytics. - - - diff --git a/docs/mini-apps/technical-reference/minikit/hooks/useClose.mdx b/docs/mini-apps/technical-reference/minikit/hooks/useClose.mdx deleted file mode 100644 index f55b1cc1..00000000 --- a/docs/mini-apps/technical-reference/minikit/hooks/useClose.mdx +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: useClose -description: Programmatically close the Mini App frame ---- - -Defined in [@coinbase/onchainkit](https://github.com/coinbase/onchainkit) - - -Allows Mini Apps to close themselves programmatically. Useful for completion flows, cancellation actions, or after successful operations. - - -## Returns - - -Function that closes the Mini App frame and returns the user to the host application. - - - -```tsx components/CloseButton.tsx -import { useClose } from '@coinbase/onchainkit/minikit'; - -export default function CloseButton() { - const close = useClose(); - - return ( - - ); -} -``` - -```tsx components/PurchaseFlow.tsx -import { useClose } from '@coinbase/onchainkit/minikit'; -import { useState } from 'react'; - -export default function PurchaseFlow() { - const close = useClose(); - const [isComplete, setIsComplete] = useState(false); - - const handlePurchase = async () => { - try { - await processPurchase(); - setIsComplete(true); - - // Auto-close after successful purchase - setTimeout(() => { - close(); - }, 2000); - } catch (error) { - console.error('Purchase failed:', error); - } - }; - - if (isComplete) { - return ( -
-

✅ Purchase Complete!

-

Closing in 2 seconds...

- -
- ); - } - - return ( -
- - -
- ); -} -``` - -```tsx components/ConfirmClose.tsx -import { useClose } from '@coinbase/onchainkit/minikit'; -import { useState } from 'react'; - -export default function ConfirmClose() { - const close = useClose(); - const [showConfirm, setShowConfirm] = useState(false); - - const handleCloseRequest = () => { - setShowConfirm(true); - }; - - const confirmClose = () => { - // Save any pending data - savePendingChanges(); - close(); - }; - - if (showConfirm) { - return ( -
-

Close Mini App?

-

Any unsaved changes will be lost.

-
- - -
-
- ); - } - - return ( -
- - {/* Your app content */} -
- ); -} -``` -
- -## Usage Patterns - -### Completion Flows -Close automatically after successful operations: - -```tsx components/CompletionFlow.tsx -const handleGameComplete = async () => { - await saveScore(finalScore); - - // Show completion screen briefly - setShowCompletion(true); - - // Auto-close after celebration - setTimeout(close, 3000); -}; -``` - -### Navigation Replacement -Use close instead of navigation for simple flows: - -```tsx components/NavigationReplacement.tsx -// Instead of navigating back, close the frame -const handleCancel = () => { - if (hasUnsavedChanges) { - confirmAndClose(); - } else { - close(); - } -}; -``` - -### Error Recovery -Provide escape routes for error states: - -```tsx components/ErrorScreen.tsx -if (hasUnrecoverableError) { - return ( -
-

Something went wrong

-

Please try again later

- -
- ); -} -``` - -## Best Practices - -### User Experience -- **Confirm important actions**: Ask before closing if user has unsaved work -- **Provide feedback**: Show completion states before auto-closing -- **Quick escape**: Always provide a way to close, especially in error states - -### Technical Considerations -- **Save state**: Persist important data before closing -- **Clean up**: Cancel ongoing requests or timers -- **Analytics**: Track close events for UX insights - -```tsx components/HandleClose.tsx -const handleClose = () => { - // Clean up - cancelPendingRequests(); - clearIntervals(); - - // Track analytics - analytics.track('mini_app_closed', { - session_duration: Date.now() - sessionStart, - completion_state: currentState - }); - - // Close - close(); -}; -``` - - -`useClose` provides a clean exit for Mini Apps. Use it thoughtfully to create polished user experiences that feel native to the host application flow. - - - diff --git a/docs/mini-apps/technical-reference/minikit/hooks/useComposeCast.mdx b/docs/mini-apps/technical-reference/minikit/hooks/useComposeCast.mdx deleted file mode 100644 index 4f75203e..00000000 --- a/docs/mini-apps/technical-reference/minikit/hooks/useComposeCast.mdx +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: useComposeCast -description: Open the cast composer with prefilled content ---- - -Defined in [@coinbase/onchainkit](https://github.com/coinbase/onchainkit) - - -Opens the native cast composer with prefilled text and embeds. Essential for viral growth and social sharing within Mini Apps. - - -## Returns - - -Function that opens the cast composer with specified content. - - - -The text content to prefill in the composer. Keep concise and engaging. - - - -Array of URLs to embed in the cast. Usually includes your Mini App URL for sharing. - - - - - -```tsx Basic Text Sharing -import { useComposeCast } from '@coinbase/onchainkit/minikit'; - -export default function ShareButton() { - const { composeCast } = useComposeCast(); - - const handleShare = () => { - composeCast({ - text: 'Just completed the daily puzzle! 🧩' - }); - }; - - return ( - - ); -} -``` - -```tsx Share with App Embed -import { useComposeCast } from '@coinbase/onchainkit/minikit'; - -export default function ShareAppButton() { - const { composeCast } = useComposeCast(); - - const handleShareApp = () => { - composeCast({ - text: 'Check out this amazing Mini App!', - embeds: [window.location.href] - }); - }; - - return ( - - ); -} -``` - -```tsx Strategic Achievement Sharing -import { useComposeCast } from '@coinbase/onchainkit/minikit'; - -export default function GameComplete({ score, level }) { - const { composeCast } = useComposeCast(); - - const shareAchievement = () => { - composeCast({ - text: `🎉 Just hit level ${level} with ${score} points!`, - embeds: [ - window.location.href, - 'https://yourgame.com/achievements/' + achievementId - ] - }); - }; - - const shareGameInvite = () => { - composeCast({ - text: 'Want to challenge me? Try to beat my high score! 🏆', - embeds: [window.location.href] - }); - }; - - return ( -
-

Congratulations! 🎉

-

Level {level} completed with {score} points

- -
- - -
-
- ); -} -``` - -```tsx Dynamic Content Sharing -import { useComposeCast } from '@coinbase/onchainkit/minikit'; -import { useState } from 'react'; - -export default function CustomShareDialog() { - const { composeCast } = useComposeCast(); - const [shareText, setShareText] = useState(''); - - const handleCustomShare = () => { - if (!shareText.trim()) return; - - composeCast({ - text: shareText, - embeds: [window.location.href] - }); - - // Clear after sharing - setShareText(''); - }; - - return ( -
-