【Twemoji】かわいい絵文字をOSで共通の画像として表示する【React】の絵文字

【Twemoji】かわいい絵文字をOSで共通の画像として表示する【React】

2022-04-27

2022-04-27

はじめに

ドライフルーツ、砂糖のせいで不健康がちこふです。

実は Twemoji は本ブログサイトにも導入したばかりですが、とても気に入っています。

Zenn を使っている時から良いな〜と感じ、埋め込むことにしました。

こんな感じです。

方針

本サイトの記事は markdown ファイルで管理しており、FrontMatter と呼ばれる場所で「タイトル、説明文、投稿日、更新日、絵文字」などを管理しています。

FrontMatter について:https://middlemanapp.com/jp/basics/frontmatter/


その絵文字の場所には、OS ごとに依存した絵文字を配置しています。

以下の写真のように、同じ絵文字でも「Windows・Mac・Android」などで別々の絵文字が使われます。

実際に以下のサイトで確認できます。

引用元サイト:https://emojipedia.org/grinning-face/

その差をなくして表示したい!という要望に答えるのが Twemoji です。画像で表現するので OS による差がなくなる、という訳です。

余談ですが、「Windows・Mac・Android」などといったのは、主に Web ブラウザからブログなどのサイトにアクセスするから、上記を挙げました。

厳密には、Windows というより Microsoft、Mac というより Apple、Android というより Google です。。。Sumsung は Garaxy などのスマホでの表示ですね。

環境

React を用いて構成していますが、React でなくても動きます。

Vue や素の JavaScript などでも同様です。

terminal

❯ node -v v16.14.0

package.json

package.json
... "dependencies": { ... "gray-matter": "^4.0.3", "react": "^17.0.2", "react-dom": "^17.0.2", "react-markdown": "^8.0.1", "twemoji-parser": "^14.0.0" }, "devDependencies": { ... "@types/node": "17.0.4", "@types/react": "17.0.38", "@types/twemoji-parser": "^13.1.1", "tailwindcss": "^3.0.7", "typescript": "4.5.4" }

ソースコードと解説

具体的なコードを用いて説明しますが、あくまで一部分に組み込むことを目的としています。

そのため、アプリケーション全体のコードは記載しません。

Markdown ファイル

以下のように FrontMatter を与えます。この絵文字は OS に依存する絵文字なので、端末によって表示が変わると思います。

example.md
--- ... emoji: '😃' ... ---

型を定義

export type MatterType = { ... emoji: string ... }

実際に parse して表示する

parseするとき、emojiundefinedになった対処として別の絵文字を渡すようにしています。

parseした結果、EmojiEntityの配列が返ってくるので、最初のものを受け取ります。

というのも、引数には絵文字を含んだ文字列を与えられるからです。例えば、parse('こんにちは😀')としても絵文字だけ返ってくるということ。

import { EmojiEntity, parse } from 'twemoji-parser' const { emoji } = data // data: MatterType const emoji: EmojiEntity = parse(emoji || '😀')[0] /// <img loading="lazy" className="" height="100px" width="100px" alt={`${title}の絵文字`} src={emoji.url} /> ...

ちなみにEmojiEntityは以下のように定義されており、urlとしてtwemojiの画像のURLが入っているので、これを img などの src として指定します。

export interface EmojiEntity { /** * @default 'emoji' */ type: typeof TypeName text: string /** * @default '' */ url: string /** * [startIndex: number, lastIndex: number] */ indices: [number, number] }

余談:絵文字は単純ではない

ご存じの方はスキップしてください。絵文字に関して知らないと、実装したり使う上でトラブルが起こる可能性があります。

僕は実際に起こりました、なんでこの絵文字は変換できるのに、別の絵文字は変換できないんだ、という感じ)


絵文字の中には、複数の絵文字の組み合わせでできた絵文字もあります。

つまり、バイト列では長くなります。

文字列長を求めると一文字ではない発生要因です。

それを対処するために必要なのが以下です。

twemoji-paser を使う理由

https://stackoverflow.com/questions/48419167/how-to-convert-one-emoji-character-to-unicode-codepoint-number-in-javascript

これを参考にコードポイントに変換できるのですが、あくまで絵文字が一文字入ってくる前提に使えるものです。

コードの型情報に絵文字型を作るのも変だな、と感じたので、絵文字だけを確実に取り出せるものが欲しかったです。

静的な Markdown ファイルの FrontMatter に emoji:””という形で書いているが、ヒューマンエラーで" "と入力してしまった場合にも対応できますね。

注意点

大量アクセスがある場合は、画像のミラーサイトやキャッシュをきちんと用意するべき、だと思います。

そういった仕組みを整えないと、CDN とは言え、リクエストが増えすぎることとなり、迷惑がかかってしまいますね。

さいごに

いかがでしたか?サイトに絵文字を可愛らしく埋め込みましょう。

参考



アバター

こふ

情報通信を専攻している大学生です。大学(研究)・趣味・アルバイトでプログラムを書いています。ITツール・サービス・文章を創作することが好きです。

ぼくについて

共有する