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
Prop | Type | Required | Default | Description |
---|---|---|---|---|
targetAddress | string | Yes | - | Bitcoin address of user to follow |
isFollowing | boolean | Yes | - | Current following state |
onFollow | () => void | Yes | - | Callback when follow action is triggered |
onUnfollow | () => void | Yes | - | Callback when unfollow action is triggered |
followText | string | No | 'Follow' | Text displayed when not following |
unfollowText | string | No | 'Following' | Text displayed when following |
disabled | boolean | No | false | Disable the button |
className | string | No | - | 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)}
/>
);
}
Related Components
- ProfileCard - Display user profiles with follow button
- ProfilePopover - Quick profile preview with follow action
- UserList - Lists of users with follow buttons
- SocialFeed - Social feed with follow interactions