npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-utterances-client

v1.1.1

Published

Another React component for using Utterances 🔮 on your website!

Downloads

27

Readme

react-utterances-client

Another React component for using Utterances 🔮 on your website!

GitHub License npm npm bundle size Buy Me A Coffee

Comments Demo

Features

  • Rewritten client.js code using React API directly in the component.
  • Written fully in TypeScript.
  • Build for both CommonJS and ES Module.
  • Named exports only.
  • Customization options.
  • Placeholder when the component is loading.
  • Event handler (onLoad, onError) support.

Table of Contents

Wait, did we have utterance-react-component already? Is another component needed?

My main motivation is to resolve the bug that I encountered when using utterance-react-component.

utterance-react-component loads the script https://utteranc.es/client.js and passes the props to that script. The problem is the component will have the same bugs as client.js and at the point I am writing this still exists.

Refer to utterances issue #624 and utterances-component issue #393.

So, I took client.js, rewrote that using React API, and made it into a React component.

Installation

Install from npm

npm install react-utterances-client
yarn add react-utterances-client

Install from repository

Recommended to specify a version tag like this for installation from the repository like below for stability.

npm install github:mddanish00/react-utterances-client#vX.X.X
yarn add react-utterances-client@github:mddanish00/react-utterances-client#vX.X.X

Check out the repository tags list here.

Remove #vX.X.X to fetch the latest changes from the main branch. Beware of instability!

Usage

Basic Usage

import { Utterances } from 'react-utterances-client';

const Comments = () => {
 return (
        <Utterances
           repo="people/example-project"
           theme="github-dark"
           issueTerm="title"
        />
 );
};

You just need to specify the repository that you will be using its issues for comments.

The repository you want to use must:

  • The repository is set to Public.
  • The utterances app is installed on the repository.
  • Make sure Issues is turned on if your repository is a fork.

After that, you can specify your theme or just omit theme prop to use the default theme and decide on issue mapping with your current page.

For this, it is better to read Blog Post ↔️ Issue Mapping on the official site for a more details explanation of the options.

You can only use one of the below props for this:

  • For pathname, url, title, og:title or specific terms, you need to use issueTerm prop.
  • For issueNumber, you need to provide the issue number to issueNumber prop.

Event Handler

import * as React from 'react';
import { Utterances } from 'react-utterances-client';

const Comments = () => {
 
    const handleLoad = React.useCallback((e)=>{
        console.log('Component is loaded!')
    }, []);

    return (
        <Utterances
           repo="people/example-project"
           theme="github-dark"
           issueTerm="title"
           onLoad={handleLoad}
        />
 );
};

Only two event handlers can be used right now:

  • onLoad: When this component finishes loading.
  • onError: When this component throws errors.

This will be attached to the iframe onLoad and onError.

The e will be passed down to the event handler.

Token Storage

This feature is experimental. It need more feedback from the users. It may be removed in later versions.

import { Utterances } from 'react-utterances-client';

const Comments = () => {
 return (
        <Utterances
           repo="people/example-project"
           issueTerm="title"
           tokenStorage="session"
        />
 );
};

Every time the user logs in to their GitHub account on the Utterances site, this component will keep the token in the redirected URL into localStorage. The problem with this is the Utterances don't provide any way to log out of the account from the site.

Also, based on my reading on the Utterances project code, the token has a 1-year expiry date.

So, I added an option to keep the token in SessionStorage instead. LocalStorage will survive when the site or tab closes but SessionStorage will auto-delete them. This is a better approach in my opinion.

The component will still set the storage to LocalStorage by default.

Recommended to create a way for the user to clear Login data like a button. Like this.

import { Utterances } from 'react-utterances-client';

const Comments = () => {
 return (
        <> 
           <button onClick={()=>localStorage.removeItem('utterances-session')}>
              Clear Login Data
           </button>
           <Utterances
              repo="people/example-project"
              issueTerm="title"
              tokenStorage="session"
           />
        </>
 );
};

Placeholder

This feature is experimental. It need more feedback from the users. It may be removed in later versions.

import { Utterances } from 'react-utterances-client';

const Comments = () => {
 return (
        <Utterances
           repo="people/example-project"
           issueTerm="title"
           placeholder={true}
        />
 );
};

Placeholder is a component that will display when the Utterances component is loading. You need to enable this feature explicitly to use it. You can even provide your own Placeholder Component through placeholder prop.

This prop will set loading prop to eager regardless what you set.

Customization

import { Utterances } from 'react-utterances-client';

const Comments = () => {
 return (
        <Utterances
           repo="people/example-project"
           theme="gruvbox-dark"
           issueTerm="title"
           iframeClassName="text-light"
           containerStyle={{ background: '#282828'}}
        />
 );
};

Theme

List of themes that are available for use with Utterances:

  • github-light
  • github-dark
  • preferred-color-scheme
  • github-dark-orange
  • icy-dark
  • dark-blue
  • photon-dark
  • boxy-light
  • gruvbox-dark

For preferred color scheme, it will depend on your OS's dark mode settings. If disabled, github-light. If enabled, github-dark.

You can see the Theme preview on the official site. Also, available in Comments Demo.

ClassName and Style

This component exposes the className prop and style prop for both Container div (containerClassName, containerStyle) and iframe (iframeClassName, iframeStyle). This opens up the possibility when customizing the appearance of the component.

For example, you can use the containerStyle prop to customize the container background.

Or, pass Bootstrap classes like text-light or bg-primary to containerClassName prop.

Or, you Emotion css function and pass the generated className to the containerClassName prop.

Go wild!

Types

import { Utterances, UtterancesProps } from 'react-utterances-client';

Types of Utterances component props are also accessible via UtteranceProps if you want to use it for some reason.

Props

|Name|Type|Required / Default|Description| |:---|:---|:-----------------|:----------| |repo|${string}/${string}|required|Comments respository for use with this component.| |label|string|""|Label that will be assigned to issues created by Utterances.| |theme|Theme|github-light|Theme that will be used by Utterances.| |issueTerm|Term or string[]|required if issueNumber undefined|Mapping the current page with terms like page URL, page title, OpenGraph title, page pathname or even your own list of terms. This prop cannot be used with issueNumber.| |issueNumber|number|required if issueTerm undefined|Mapping the current page with a specific issue number in the repository. This prop cannot be used with issueTerm.| |loading|lazy or eager|lazy|Indicates when the browser should load this component. In this case, you want to modify the default behaviour for some reason.| |onLoad|(e) => void|undefined|Event callback when this component finish loading.| |onError|(e) => void|undefined|Event callback when this component throw errors.| |tokenStorage|local or session|local|Browser Storage that you want to use to keep your token. session to sessionStorage, local to LocalStorage.| |placeholder|boolean or React.ReactElement|false|Placeholder when this component is still loading. You can disable, or enable it with a default placeholder or provide your own placeholder component. This also will force loading prop to eager regardless what you set.| |containerClassName|string|undefined|ClassName of the Utterances iframe container.| |iframeClassName|string|undefined|ClassName of the Utterances iframe.| |containerStyle|React.CSSProperties|{}|Style of the Utterances iframe container.| |iframeStyle|React.CSSProperties|{}|Style of the Utterances iframe.|

Like this project?

Star this project if it is useful for you.

Also, consider buying me a coffee!

"Buy Me A Coffee"

Plan

We need to break down what client.js does.

  • Processing the provided props
  • Collect attributes from the page that the script loaded from
  • And, finally, construct the URL based on those information and load iframe with that URL.

As the name implies, the client.js is just a client. And so is this component.

I will implement everything that client.js can do and also any future updates for client.js. I also will consider any suggestions that will improve the component itself.

I can fix it if something is wrong with the client functions above.

But if you want new features and have problems with Utterances itself, you have better luck in posting your issues in the Utterances repository instead.

License

This project is licensed under the MIT license.

Other Licenses

Some of the functions in this library are based on the original client.ts in the Utterances repository that is licensed under the MIT license.

The types of the project are taken and modified from TomokiMiyauci/utterance-component repository that is licensed under the MIT license.

Icon SVG that is used as the demo icon, 🔮 is a part of the googlefonts/noto-emoji(https://github.com/googlefonts/noto-emoji) project that is licensed under the Apache License 2.0.

The dev-only hook, useUtterancesSession is based on useLocalStorage and useSessionStorage hooks from @uidotdev/usehooks project that is licensed under the MIT license.