clap & like button on React

React docs

Lyket is the ultimate tool to add like buttons, applause buttons and like/dislike buttons to your React app! The library allows a great deal of customization with just a few lines of code and it's compatible with all React frameworks like NextJS, Gatsby, create-react-app.

If you want to find out how to use the React library in detail you came to the right place. If you prefer to learn with examples and ready-made snippets to copy and paste, you can visit:

How the buttons work

All Lyket buttons share these basic behaviors and features:

  • As soon as a button component is mounted, a fetch request is made to retrieve info on the button that identifies with the ID and namespace that you provided. If no button is found, a new one will be created using the ID/namespace identifier.

  • Notice that the server will create a new button for every different and unique identifier, so if you change ID or namespace or type the new button won’t inherit the votes.

  • Every time a visitor interacts with a button, the button counter will update and Lyket will flag that the visitor has voted. Lyket uses an unique random ID stored in the visitor's browser localStorage to identify the visitor, with no need to signup or to use any third party service. To disable the session ID, and therefore use only the IP address to identify a user, set the disableSessionId prop to true in the Provider component.

  • Lyket enforces a maximum number of sessions IDs per IPaddress to avoid receiving too many requests or DDoS attacks. The default is 3 sessions per IP. You can change this number by logging into your private area and edit the user settings.

  • In the user settings you can also specify from which domains Lyket should accept requests using your personal API key. If left empty Lyket will accept requests coming from all domains.

Installation

Well, Let's get started! To install the component run

yarn add @lyket/react

or

npm install @lyket/react
Add Lyket to your app

Add the Provider component top-level and configure it using your personal public API key that you can get after registering to Lyket

import { Provider } from '@lyket/react';

ReactDOM.render(
  <Provider apiKey="[YOUR-API-KEY]">
    <App />
  </Provider>,
  document.getElementById('root')
);
Required props
  • apiKey: string - You can get your public API key by registering on Lyket.
Optional props
  • theme: Record<'colors' | 'fonts' , Record<string, string>> - Allows you to change the default buttons colors and fonts. It doesn't apply to all templates. Read more about it in the Styling buttons section at the end of this document.

  • recaptchaSiteKey: string - If you enabled reCAPTCHA in the private area's user settings, you need to provide your reCAPTCHA public key, otherwise your buttons will result as unauthorized. Read more in the reCAPTCHA section at the end of this document.

  • disableSessionId: boolean Default: false - If set to true Lyket won't store a unique session ID for your visitors making them anonymous. Lyket will then discriminate visitors (to tell if they already liked a button or not) only based on the IP address. Disabling the session ID can be useful if you don't want Lyket to result in your cookie detection software.

Configuring the buttons

Once you configured the Provider you can start adding buttons anywhere in your app. You can choose among three different button types that have different behaviors and purposes, but all share these required and optional props:

Required props
  • id: string - The API uses the ID to find a button. It should be unique for namespace. It accepts an alphanumeric string with maximum 50 characters.
Optional props
  • namespace: string - Giving a namespace is useful to keep buttons organised, and can be used to fetch statistics. Check the API docs for more information.

  • hideCounterIfLessThan: number - You may want to hide the counter if you are not getting enough feedback. Specify the number of votes/claps/likes you want to receive before showing the counter.

  • component: React.ReactNode - If this prop is not provided you will see the Simple template. To change the aspect of your buttons you can either choose one of the ready-made templates or a custom component and pass it through the component attribute.

  • onLoad: (buttonData: UpdownButtonData | ClapButtonData | LikeButtonData) => void - This function gets called when the button has finished loading. buttonData has different format depending on the button type.

Button types

The three types of buttons are the following:

Button Templates

Lyket provides a set of out-of-the-box templates. You can see all the available templates in the templates page

By default, ie. if you don't specify any template or custom component, Lyket will show the Simple Template.

LikeButton Templates
  • Simple (default) - supports custom theme
  • Twitter: Twitter style
  • Chevron: Chevron style - supports custom theme
UpdownButton Templates
  • Simple (default) - supports custom theme
  • Reddit: Reddit style
  • Chevron: Chevron style - supports custom theme
ClapButton Templates
  • Simple (default) - supports custom theme
  • Medium: Medium style
  • Heart: Heart style - supports custom theme

Import templates directly from the button. Here is an example of using the Twitter template on a LikeButton.

import { LikeButton } from '@lyket/react';

export StandingOvation = () => {
  return (
    <>
      <h4 id="Do you like pizza?">Do you like pizza?</h4>
      <LikeButton
        id="do-you-like-pizza"
        component={ClapButton.templates.Twitter}
      />
    </>
  );
};
Like Button

Like buttons behave like Twitter like buttons.

Visitors can only like once and a subsequent request from the same visitor will remove the visitor's like.

import { LikeButton } from '@lyket/react';

export BlogPost = ({ title, content }) => {
  return (
    <div>
      {title}
      <LikeButton
        id="how-to-reduce-footprint"
        namespace="post"
      />
      {content}
    </div>
    );
  };
Try it! β†’
Optional props
  • onPress: (buttonData: LikeButtonData) => void - This function gets called whenever a Press action is triggered.

LikeButtonData

  • id: string
  • type: "like_button"
  • attributes: Object
    • namespace: string
    • namespaceRank: number
    • totalLikes: number
    • totalRank: number
    • totalVotes: number
    • userLiked: boolean
Like/Dislike Button

Up/down buttons behave like Reddit like/dislike buttons.

Visitors can only like or dislike once and a subsequent action from the visitor will remove the visitor's like or dislike.

import { UpdownButton } from '@lyket/react';

export BlogPost = ({ title, content }) => {
  return (
    <div>
      {title}
      <UpdownButton
        id="how-i-joined-the-raiders-of-the-lost-ark"
        namespace="post"
      />
      {content}
    </div>
  );
};
Try it! β†’
-
Optional props
  • onPressUp: (buttonData: UpdownButtonData) => void - This function gets called whenever a PressUp action is triggered.

  • onPressDown: (buttonData: UpdownButtonData) => void - This function gets called whenever a PressDown action is triggered.

UpdownButtonData:

  • id: string
  • type: "updown_button"
  • attributes: Object
    • namespace: string
    • namespaceRank: number
    • totalScore: number
    • totalRank: number
    • totalVotes: number
    • userVoteDirection: -1 | 0 | 1
Clap Button

Clap buttons behave like Medium applauses.

Visitors can like multiple times and every other call from the same visitor will increment the claps number indefinitely.

import { ClapButton } from '@lyket/react';

export BlogPost = ({ title, content }) => {
  return (
    <div>
      {title}
      <ClapButton id="diy-fish-holder" namespace="post" />
      {content}
    </div>
  );
};
Try it! β†’
0
Optional props
  • onPress: (buttonData: ClapButtonData) => void - This function gets called whenever a Press action is triggered.

ClapButtonData:

  • id: string
  • type: "clap_button"
  • attributes: Object
    • namespace: string
    • namespaceRank: number
    • totalClaps: number
    • totalRank: number
    • userClaps: number

Custom Buttons

You may want to give a different flavour to a button, for example using your company logo as the icon. You can do that by creating your own custom button!

Here is an example for each button type of using a custom component by passing it as "children". You can pass a custom component also through the component prop.

Custom Like Button

The clap button component allows you to customize the look and feel of your button, like changing the icon, show or hide the counter and so on. These are the available props:

import { LikeButton } from '@lyket/react';

export Faq = () => {
  return (
    <>
      <h4 id="Do you like pizza?">Do you like pizza?</h4>
      <LikeButton
        id="do-you-like-pizza"
        namespace="faq"
        hideCounterIfLessThan={1}
      >
        {({
          handlePress,
          totalLikes,
          userLiked,
          isLoading,
          isCounterVisible
        }) => (
          <>
            <button onClick={handlePress} disabled={isLoading}>
              πŸ•
            </button>
            {isCounterVisible && <div>Total: {totalLikes}</div>}
            {userLiked && <div>Great! I like pizza as well!</div>}
          </>
        )}
      </LikeButton>
    </>
  )
};
Try! β†’
Total likes: 0

Custom ClapButton

The clap button component allows you to customize the look and feel of your button, like changing the icon, show or hide the counter and so on. These are the available props:

  • handlePress: (buttonData: ClapButtonData) => void
  • totalClaps: number
  • userClaps: number
  • isLoading: boolean
  • isCounterVisible: boolean
import { ClapButton } from '@lyket/react';

export Faq = () => {
  return (
    <>
      <h4 id="Do you like pizza?">Do you like pizza?</h4>
      <ClapButton
        id="do-you-like-pizza"
        namespace="faq"
        hideCounterIfLessThan={3}
      >
        {({
          handlePress,
          totalClaps,
          userClaps,
          isLoading,
          isCounterVisible,
        }) => (
          <>
            <button onClick={handlePress} disabled={isLoading}>
              πŸ‘
            </button>
            {isCounterVisible && <div>Total: {totalClaps}</div>}
            <div>You clapped {userClaps} times</div>
          </>
        )}
      </ClapButton>
    </>
  );
};
Try! β†’
Total claps: 0
You clapped 0 times!

Custom Like/Dislike Button

Like/dislike component allows you to customize the look and feel of your button, like changing the icon, show or hide the counter and so on. These are the available props:

  • handlePressUp: (buttonData: ClapButtonData) => void
  • handlePressDown: (buttonData: ClapButtonData) => void
  • totalClaps: number
  • userClaps: number
  • isLoading: boolean
  • isCounterVisible: boolean
import { UpdownButton } from '@lyket/react';

export Faq = () => {
  return (
    <>
      <h4 id="Do you like pizza?">Do you like pizza?</h4>
      <UpdownButton
        id="do-you-like-pizza"
        namespace="faq"
        hideCounterIfLessThan={1}
      >
        {({
          handlePressUp,
          handlePressDown,
          totalScore,
          userVoteDirection,
          isCounterVisible,
          isLoading,
        }) => (
          <>
            <button onClick={handlePressUp} disabled={isLoading}>
              + πŸ•
            </button>
            <button onClick={handlePressDown} disabled={isLoading}>
              - πŸ•
            </button>
            <div>Total votes: {totalScore}</div>
            <div>
              {
                userVoteDirection > 0
                ? ":D"
                : userVoteDirection === 0
                ? "waiting for vote..."
                : ":("
              }
            </div>
          </>
        )}
      </UpdownButton>
    </>
  );
};
Try! β†’
or
Total votes: 0
waiting for vote...

Apply custom styling to the button templates

Resizing

All button templates can be resized by wrapping them in a container and changing the font-size.

Apply your color scheme and fonts

Lyket uses the theme-ui library, allowing you to provide your own color palette to the buttons through the theme prop in the provider. Colors support rgba, hex, and color names.

Button colors
  • primary - Changes the background color of the "like" button, when user has liked.
  • secondary - Changes the background color of the "dislike" button, when user has disliked.
  • background - Changes the background color of the inactive button.
  • text - Changes the counter text color.
  • icon - Changes the icon's color.
  • highlight - Changes the animation color.
Button fonts
  • body - Changes counter font.

These are the default values:

const defaultTheme = {
  colors: {
    primary: '#22c1c3',
    secondary: '#ff00c3',
    background: 'transparent',
    text: '#292929',
    highlight: '#e095ed',
    icon: '#292929',
  },
  fonts: {
    body: 'inherit',
  },
};

The Provider component makes a deep merge, so you can overwrite the theme object totally or partially.

Not all the templates support theming. Read the templates detail to know which ones.

reCAPTCHA

Lyket is integrated with Google reCAPTCHA V3 to handle malicious use without interrupting human users. To enable it you need to provide your Google reCAPTCHA secret key in the user settings in the private area and add your recaptcha site key through the recaptchaSiteKey prop in the Provider. The key will be encrypted.

In this way each time a user interacts with a button an "invisible" reCAPTCHA check will be performed, keeping your website safe.

Be aware that if you only set reCAPTCHA secret key in the user settings while not passing the reCAPTCHA site key in your Provider, the buttons won't work.