DocsComponentsFollow Button

Follow Button

The Follow Button component allows users to manage their social connection with another user. It displays the current relationship status between the lookupAddress and the connectedAddress and provides actions to change this state, including new reciprocal actions like “Block Back” and “Mute Back”.

Features

  • Error Display: Shows error messages via tooltip (title attribute)
  • Visual Feedback: Error CSS class with shake animation when errors occur
  • Error Recovery: Automatically clears errors when user retries the action
  • Enhanced Accessibility: Built-in ARIA attributes for screen reader support
  • Improved Disabled State: Combines prop-based and computed disabled states
  • Reciprocal Actions: “Block Back” and “Mute Back” functionality when the other user has blocked or muted you

Add to your project

Add Transaction Modal component

Follow button will work with the Transaction Modal component to handle the transaction flow, therefore you need to add the Transaction Modal component to your project. Make sure to add the Transaction Provider to your project as well. For all the other providers take a look at the setup documentation.

import { TransactionProvider, TransactionModal } from 'ethereum-identity-kit'
 
export default function App() {
  return (
    // Other Providers
    <TransactionProvider>
      <TransactionModal />
    </TransactionProvider>
  )
}

Add Follow Button component

Add the follow button wherever you wish, give it the lookupAddress and connectedAddress props, and you are good to go.

import FollowButton from 'ethereum-identity-kit'
 
export default function YourComponent() {
  return (
    <FollowButton
      lookupAddress="0x123..."
      connectedAddress="0xabc..."
      onDisconnectedClick={() => alert('Please connect your wallet')}
    />
  )
}
Try it out! - https://playground.ethidentitykit.com/?path=/story/organisms-follow-button-transaction-modal--single-transaction

Follow button for vitalik.eth - 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

Parameters

ParameterDescriptionRequiredDefault Value
lookupAddressThe address of the user to follow or unfollow.Yes-
connectedAddressThe address of the currently connected user.No-
selectedListThe EFP list number to manage follow state for. (defaults to connectedAddress)No-
disabledDisables the button if set to true.Nofalse
onDisconnectedClickFunction to call when the button is clicked and the user is not connected.No-
customOnClickCustom click handler that receives current button state as parameter.No-
soundsObject containing sound files to play on button actions.No-
customClassNameCustom CSS class names to apply to the button. (overwrites the default styles)No-
customLoaderCustom loader component to display while loading.No-
propsAdditional HTML button element props.No-

The component now includes automatic address validation. Invalid addresses will display an error message in the button’s tooltip.

The onDisconnectedClick function is optional but recommended to handle cases where the user is not connected.

Button States

The Follow Button intelligently detects and displays different states based on the relationship between users:

Standard States

  • Follow: User can follow the other user
  • Following: User is currently following the other user
  • Blocked: User has blocked the other user
  • Muted: User has muted the other user

Reciprocal States (New in v0.2.54)

  • Block Back: Displayed when the other user has blocked you, allowing you to block them in return
  • Mute Back: Displayed when the other user has muted you, allowing you to mute them in return

These reciprocal states help users manage their social boundaries more effectively by providing quick actions to respond to blocks and mutes.

Styling

The component uses predefined styles from FOLLOW_BUTTON_STYLES and can be further customized using the className prop. The button’s appearance changes based on its state:

  • Normal states: Follow, Following, Blocked, Muted, etc.
  • Reciprocal states: Block Back, Mute Back (when the other user has blocked/muted you)
  • Pending states: Shows loading indicator
  • Disabled state: Reduced opacity and no hover effects
  • Error state: Adds shake animation and error styling
/* Example error animation */
.follow-button.error {
  animation: shake 0.5s;
  border-color: #ef4444;
}
 
@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  25% {
    transform: translateX(-5px);
  }
  75% {
    transform: translateX(5px);
  }
}

Sound Effects

You can provide sound effects for different button states by passing a sounds object. Each key in the object corresponds to a button state, and the value is the path to the sound file.

<FollowButton
  lookupAddress="0x123..."
  connectedAddress="0xabc..."
  sounds={{
    follow: '/sounds/follow.mp3',
    unfollow: '/sounds/unfollow.mp3',
    ...
  }}
/>

Custom Click Handler

You can provide a custom click handler to override or extend the default button behavior:

<FollowButton
  lookupAddress="0x123..."
  connectedAddress="0xabc..."
  customOnClick={(buttonState) => {
    console.log('Button clicked with state:', buttonState)
    // Add custom logic here
    // Return true to prevent default action, false to continue
    return false
  }}
/>

The customOnClick handler receives the current button state and can return a boolean to control default behavior.

The sounds prop is optional and can enhance user experience with auditory feedback.

Accessibility

The Follow Button includes comprehensive accessibility features:

<FollowButton lookupAddress="0x123..." connectedAddress="0xabc..." />
// Renders with:
// - aria-label="Follow vitalik.eth" (or appropriate action)
// - aria-pressed={true/false} (for following state)
// - title={error} (when errors occur)

Error Handling

Errors are displayed as tooltips and trigger visual feedback:

// When an error occurs:
// 1. Error message appears in title attribute
// 2. Button gets 'error' CSS class
// 3. Shake animation plays
// 4. Error clears automatically on retry

Custom Loader

If you want to use a custom loader while the button is in a loading state, pass a React component to the customLoader prop.