Skip to content

Instantly share code, notes, and snippets.

@chibicode
Last active September 29, 2024 04:18
Show Gist options
  • Save chibicode/fe195d792270910226c928b69a468206 to your computer and use it in GitHub Desktop.
Save chibicode/fe195d792270910226c928b69a468206 to your computer and use it in GitHub Desktop.
A dead simple React.js Twemoji component.

Twemoji + React

A dead simple React Twemoji component.

Requirements: twemoji

npm install --save twemoji

# or

yarn add twemoji
import React from 'react'
import Twemoji from './Twemoji'
const Example = () => (
<p>
Hello! <Twemoji emoji="👋" />
</p>
)
export default Example
.emoji {
display: inline-block;
width: auto;
height: 1em;
vertical-align: -0.125em;
}
import React, { memo } from 'react'
import twemoji from 'twemoji'
const Twemoji = ({ emoji }) => (
<span
dangerouslySetInnerHTML={{
__html: twemoji.parse(emoji, {
folder: 'svg',
ext: '.svg'
})
}}
/>
)
export default memo(Twemoji)
@zhe
Copy link

zhe commented Feb 18, 2020

Thanks for the code example!

@DoctorDerek
Copy link

Solid, thanks!

@DoctorDerek
Copy link

Since Twemoji doesn't play nicely with any type of custom Image component, like the drop-in Image replacement in Next.js, I ended up simplifying things even further:

// Twemoji.js
import React, { memo } from "react"
import Image from "next/image"

const isRequired = () => {
  throw new Error("You need to specify an emoji for the Twemoji component")
}

const Twemoji = ({ emoji = isRequired() }) => {
  const img = emoji.codePointAt(0).toString(16)

  console.log(img)
  return (
    <Image
      src={`https://twemoji.maxcdn.com/v/latest/svg/${img}.svg`}
      height="72"
      width="72"
      alt={emoji}
    />
  )
}

export default memo(Twemoji)

You'll need to add domains: ["twemoji.maxcdn.com"] to the appropriate place in the next.config.js file to make this work.

You could debate specifying alt="" instead of alt={emoji} for this type of decorative use of an emoji, but I think it's fine.

This is also a more programmer-friendly version than trying to comply with ESLint's emoji rule for a11y.

Thanks for the help @chibicode !

@ShahriarKh
Copy link

@DoctorDerek Brilliant! Thanks.

@svirins
Copy link

svirins commented Jul 14, 2022

@DoctorDerek You save me couple of hours! Thanks.

@nekochan0122
Copy link

nekochan0122 commented Jul 22, 2022

Fix : 30-fe0f-20e3.svg => 30-20e3.svg .

import React from 'react'
import NextImage from 'next/image'
import twemoji from 'twemoji'

const U200D = String.fromCharCode(0x200d)
const UFE0Fg = /\uFE0F/g

function Twemoji({
  emoji,
  ext = 'svg',
  width = 72,
  height = 72,
}: {
  emoji: string
  ext?: 'svg' | 'png'
  width?: number | string
  height?: number | string
}) {
  const HEXCodePoint = twemoji.convert.toCodePoint(
    emoji.indexOf(U200D) < 0 ? emoji.replace(UFE0Fg, '') : emoji
  )

  return (
    <NextImage
      src={`https://twemoji.maxcdn.com/v/latest/${ext === 'png' ? '72x72' : 'svg'}/${HEXCodePoint}.${ext}`}
      width={width}
      height={height}
      alt={emoji}
      draggable={false}
    />
  )
}

export default React.memo(Twemoji)

@lmssieh
Copy link

lmssieh commented Sep 1, 2022

@NekoChanTaiwan works great, thanks for sharing!

@dejurin
Copy link

dejurin commented May 15, 2023

UPDATE

import React from 'react';
import NextImage from 'next/image';
import twemoji from 'twemoji';

const U200D = String.fromCharCode(0x200d);
const UFE0Fg = /\uFE0F/g;

function Twemoji({
  emoji,
  ext = 'svg',
  width = 72,
  height = 72,
}: {
  emoji: string
  ext?: 'svg' | 'png'
  width?: number
  height?: number
}) {
  const HEXCodePoint = twemoji.convert.toCodePoint(
    emoji.indexOf(U200D) < 0 ? emoji.replace(UFE0Fg, '') : emoji,
  );

  return (
    <NextImage
      src={`https://twemoji.maxcdn.com/v/latest/${ext === 'png' ? '72x72' : 'svg'}/${HEXCodePoint}.${ext}`}
      width={width}
      height={height}
      alt={emoji}
      loading="lazy"
      draggable={false}
    />
  );
}

export default React.memo(Twemoji);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment