Skip to main content
What you’ll learn
By the end of this guide, you’ll be able to:
  • Implement deeplinks for direct messaging with agents
  • Create seamless user flows between group and private conversations
  • Follow best practices for deeplink implementation
  • Handle fallbacks and cross-client compatibility

Overview

Deeplinks enable seamless navigation within Base App, allowing agents to create more engaging and intuitive user experiences. The most common use case is directing users to start a private conversation with an agent from a group chat context.

Use Case

Your miniapp has an agent and you want to encourage people to chat with the agent directly. Or, your agent exists in a group chat context and wants users to interact with it privately. You could add a button like “Chat with me” and use this deeplink.

Syntax

cbwallet://messaging/address

Parameters

  • address — The 0x address of the user you want to chat with (in hex format, e.g., 0xabc...1234)

Implementation Examples

Basic Button Implementation:
<button 
  onClick={() => openUrl("cbwallet://messaging/0x5993B8F560E17E438310c76BCac1Af3E6DA2A58A")} 
  className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg"
>
  Chat with me privately
</button>
React Component with Error Handling:
import { useState } from 'react';

interface DeeplinkButtonProps {
  agentAddress: string;
  label?: string;
  className?: string;
}

export function DeeplinkButton({ 
  agentAddress, 
  label = "Direct Message",
  className = "btn-primary" 
}: DeeplinkButtonProps) {
  const [isLoading, setIsLoading] = useState(false);

  const handleDeeplink = async () => {
    setIsLoading(true);
    try {
      const deeplink = `cbwallet://messaging/${agentAddress}`;
      
      // Check if running in supported environment
      if (typeof window !== 'undefined') {
        window.location.href = deeplink;
      } else {
        // Fallback for server-side rendering
        console.warn('Deeplink not supported in this environment');
      }
    } catch (error) {
      console.error('Failed to open deeplink:', error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <button 
      onClick={handleDeeplink}
      disabled={isLoading}
      className={className}
    >
      {isLoading ? 'Opening...' : label}
    </button>
  );
}