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.

Core Principles

Use SDK Actions for Cross-Client Compatibility

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.
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.

External Navigation

Opening External URLs

Use sdk.actions.openUrl() to safely open external websites in the client’s in-app browser:
App.tsx
import { sdk } from '@@farcaster/miniapp-sdk';

// Correct: Use SDK action
const openExternalSite = () => {
  sdk.actions.openUrl('https://example.com');
};

// Incorrect: Direct HTML link
// <a href="https://example.com">Visit Site</a>

Composing Casts

Use sdk.actions.composeCast() instead of composer intent URLs:
App.tsx
import { sdk } from '@farcaster/miniapp-sdk';

// Correct: Use SDK action
const shareContent = () => {
  sdk.actions.composeCast({
    text: 'Check out this Mini App!',
    embeds: ['https://yourminiapp.com']
  });
};

// Incorrect: Composer intent URLs
// window.open('https://farcaster.com/~/compose?text=...')

Best Practices

1. Prioritize SDK Actions

Before implementing any navigation or linking functionality:
  1. Check if an official SDK action exists for your use case
  2. Use the SDK action instead of crafting custom URLs
  3. Test across multiple clients to ensure compatibility

2. Handle Unsupported Features Gracefully

When using features that may not be supported in all clients:
App.tsx
import { sdk } from '@@farcaster/miniapp-sdk';

const handleExternalLink = (url) => {
  try {
    sdk.actions.openUrl(url);
  } catch (error) {
    // Fallback behavior for unsupported clients
    console.log('External navigation not supported');
  }
};

3. Avoid Client-Specific URLs

Don’t hardcode URLs specific to particular clients (like Warpcast URLs). Instead, use SDK actions that work across all supported clients.

Common Patterns

NavigationComponent.tsx
import { sdk } from '@@farcaster/miniapp-sdk';

const NavigationComponent = () => {
  const handleExternalLink = () => {
    sdk.actions.openUrl('https://docs.example.com');
  };

  const handleShare = () => {
    sdk.actions.composeCast({
      text: 'Just used this amazing Mini App!',
      embeds: [window.location.href]
    });
  };

  return (
    <div>
      <button onClick={handleExternalLink}>
        View Documentation
      </button>
      <button onClick={handleShare}>
        Share This App
      </button>
    </div>
  );
};

Conditional Navigation

ConditionalNavigation.tsx
import { sdk } from '@@farcaster/miniapp-sdk';

const ConditionalNavigation = () => {
  const context = sdk.context;
  
  const handleNavigation = () => {
    // Adapt behavior based on client capabilities
    if (context.client.clientFid) {
      sdk.actions.openUrl('https://app-specific-url.com');
    } else {
      // Fallback for other clients
      window.open('https://fallback-url.com', '_blank');
    }
  };

  return (
    <button onClick={handleNavigation}>
      Open External Resource
    </button>
  );
};

Migration Guide

If your Mini App currently uses static URLs or direct links, update them using these patterns:
Current ImplementationRecommended SDK Action
<a href="https://external.com">sdk.actions.openUrl('https://external.com')
window.open('https://farcaster.com/~/compose?text=...')sdk.actions.composeCast({ text: '...', embeds: [...] })
Farcaster-specific deeplinksUse appropriate SDK action
Direct profile linksUse SDK actions for profile navigation when available

Future Considerations

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.