BigBlocks Docs
Components/Social

FollowButton

Follow and unfollow users with Bitcoin-based social interactions

BitcoinAuthProvider
socialactionsui

A social interaction component that allows users to follow and unfollow other users using Bitcoin-based authentication. Integrates with the BigBlocks social system.

Demo

Installation

npx bigblocks add follow-button

Import

import { FollowButton } from 'bigblocks';

Basic Usage

<FollowButton
  targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  isFollowing={false}
  onFollow={() => console.log('Following user')}
  onUnfollow={() => console.log('Unfollowing user')}
/>

Props

PropTypeRequiredDefaultDescription
targetAddressstringYes-Bitcoin address of user to follow
isFollowingbooleanYes-Current following state
onFollow() => voidYes-Callback when follow action is triggered
onUnfollow() => voidYes-Callback when unfollow action is triggered
followTextstringNo'Follow'Text displayed when not following
unfollowTextstringNo'Following'Text displayed when following
disabledbooleanNofalseDisable the button
classNamestringNo-Additional CSS classes
size'sm' | 'md' | 'lg'No'md'Button size

Examples

Basic Follow Button

<FollowButton
  targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  isFollowing={false}
  onFollow={handleFollow}
  onUnfollow={handleUnfollow}
/>

Custom Text

<FollowButton
  targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  isFollowing={false}
  followText="Subscribe"
  unfollowText="Subscribed"
  onFollow={handleSubscribe}
  onUnfollow={handleUnsubscribe}
/>

Different Sizes

{/* Small */}
<FollowButton
  targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  isFollowing={false}
  size="sm"
  onFollow={handleFollow}
  onUnfollow={handleUnfollow}
/>

{/* Medium (default) */}
<FollowButton
  targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  isFollowing={false}
  size="md"
  onFollow={handleFollow}
  onUnfollow={handleUnfollow}
/>

{/* Large */}
<FollowButton
  targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  isFollowing={false}
  size="lg"
  onFollow={handleFollow}
  onUnfollow={handleUnfollow}
/>

With Loading State

<FollowButton
  targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  isFollowing={isFollowing}
  disabled={loading}
  onFollow={async () => {
    setLoading(true);
    await followUser(targetAddress);
    setLoading(false);
  }}
  onUnfollow={async () => {
    setLoading(true);
    await unfollowUser(targetAddress);
    setLoading(false);
  }}
/>

Backend Integration

The FollowButton integrates with the BigBlocks social API endpoints:

Required Headers

headers: {
  'X-Auth-Token': '<BSM signature>',
  'X-Decrypted-Backup': '<optional for multi-profile>',
  'Content-Type': 'application/json'
}

Follow User

POST /api/social/follow

Request Body:
{
  targetAddress: string;
}

Response:
{
  success: boolean;
  followId?: string;
  message?: string;
}

Unfollow User

DELETE /api/social/follow

Request Body:
{
  targetAddress: string;
}

Response:
{
  success: boolean;
  message?: string;
}

Usage Patterns

In Profile Cards

import { ProfileCard, FollowButton } from 'bigblocks';

export function UserProfile({ user, currentUser }) {
  const [isFollowing, setIsFollowing] = useState(user.isFollowed);

  return (
    <ProfileCard profile={user}>
      {currentUser.address !== user.address && (
        <FollowButton
          targetAddress={user.address}
          isFollowing={isFollowing}
          onFollow={() => setIsFollowing(true)}
          onUnfollow={() => setIsFollowing(false)}
        />
      )}
    </ProfileCard>
  );
}

In User Lists

import { FollowButton } from 'bigblocks';

export function UserList({ users, followStates, onFollowChange }) {
  return (
    <div className="space-y-4">
      {users.map(user => (
        <div key={user.address} className="flex items-center justify-between p-4 border rounded">
          <div className="flex items-center gap-3">
            <img src={user.avatar} className="w-10 h-10 rounded-full" />
            <div>
              <h3 className="font-medium">{user.name}</h3>
              <p className="text-sm text-muted-foreground">{user.bio}</p>
            </div>
          </div>
          <FollowButton
            targetAddress={user.address}
            isFollowing={followStates[user.address] || false}
            onFollow={() => onFollowChange(user.address, true)}
            onUnfollow={() => onFollowChange(user.address, false)}
          />
        </div>
      ))}
    </div>
  );
}

With Analytics

import { FollowButton } from 'bigblocks';
import { analytics } from '@/lib/analytics';

export function TrackedFollowButton({ targetAddress, ...props }) {
  const handleFollow = () => {
    analytics.track('user_followed', {
      targetAddress,
      timestamp: Date.now()
    });
    props.onFollow?.();
  };

  const handleUnfollow = () => {
    analytics.track('user_unfollowed', {
      targetAddress,
      timestamp: Date.now()
    });
    props.onUnfollow?.();
  };

  return (
    <FollowButton
      {...props}
      targetAddress={targetAddress}
      onFollow={handleFollow}
      onUnfollow={handleUnfollow}
    />
  );
}

State Management

Using React State

import { useState } from 'react';
import { FollowButton } from 'bigblocks';

export function FollowExample() {
  const [follows, setFollows] = useState<Record<string, boolean>>({});

  const handleFollow = (address: string) => {
    setFollows(prev => ({ ...prev, [address]: true }));
  };

  const handleUnfollow = (address: string) => {
    setFollows(prev => ({ ...prev, [address]: false }));
  };

  return (
    <FollowButton
      targetAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
      isFollowing={follows["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"] || false}
      onFollow={() => handleFollow("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa")}
      onUnfollow={() => handleUnfollow("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa")}
    />
  );
}

Using Context

import { createContext, useContext } from 'react';
import { FollowButton } from 'bigblocks';

const SocialContext = createContext();

export function FollowWithContext({ targetAddress }) {
  const { isFollowing, follow, unfollow } = useContext(SocialContext);

  return (
    <FollowButton
      targetAddress={targetAddress}
      isFollowing={isFollowing(targetAddress)}
      onFollow={() => follow(targetAddress)}
      onUnfollow={() => unfollow(targetAddress)}
    />
  );
}