
【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
1❯ node -v 2v16.14.0
package.json
package.json1... 2"dependencies": { 3 ... 4 "gray-matter": "^4.0.3", 5 "react": "^17.0.2", 6 "react-dom": "^17.0.2", 7 "react-markdown": "^8.0.1", 8 "twemoji-parser": "^14.0.0" 9 }, 10 "devDependencies": { 11 ... 12 "@types/node": "17.0.4", 13 "@types/react": "17.0.38", 14 "@types/twemoji-parser": "^13.1.1", 15 "tailwindcss": "^3.0.7", 16 "typescript": "4.5.4" 17 }
ソースコードと解説
具体的なコードを用いて説明しますが、あくまで一部分に組み込むことを目的としています。
そのため、アプリケーション全体のコードは記載しません。
Markdown ファイル
以下のように FrontMatter
を与えます。この絵文字は OS
に依存する絵文字なので、端末によって表示が変わると思います。
example.md1--- 2... 3emoji: '😃' 4... 5---
型を定義
1export type MatterType = { 2 ... 3 emoji: string 4 ... 5}
実際に parse して表示する
parse
するとき、emoji
がundefined
になった対処として別の絵文字を渡すようにしています。
parse
した結果、EmojiEntity
の配列が返ってくるので、最初のものを受け取ります。
というのも、引数には絵文字を含んだ文字列を与えられるからです。例えば、parse('こんにちは😀')
としても絵文字だけ返ってくるということ。
1import { EmojiEntity, parse } from 'twemoji-parser' 2const { emoji } = data 3// data: MatterType 4const emoji: EmojiEntity = parse(emoji || '😀')[0] 5/// 6<img 7 loading="lazy" 8 className="" 9 height="100px" 10 width="100px" 11 alt={`${title}の絵文字`} 12 src={emoji.url} 13/> 14...
ちなみにEmojiEntity
は以下のように定義されており、url
としてtwemoji
の画像のURL
が入っているので、これを img などの src として指定します。
1export interface EmojiEntity { 2 /** 3 * @default 'emoji' 4 */ 5 type: typeof TypeName 6 text: string 7 /** 8 * @default '' 9 */ 10 url: string 11 /** 12 * [startIndex: number, lastIndex: number] 13 */ 14 indices: [number, number] 15}
余談:絵文字は単純ではない
ご存じの方はスキップしてください。絵文字に関して知らないと、実装したり使う上でトラブルが起こる可能性があります。
僕は実際に起こりました、なんでこの絵文字は変換できるのに、別の絵文字は変換できないんだ、という感じ)
絵文字の中には、複数の絵文字の組み合わせでできた絵文字もあります。
つまり、バイト列では長くなります。
文字列長を求めると一文字ではない発生要因です。
それを対処するために必要なのが以下です。
twemoji-paser を使う理由
これを参考にコードポイントに変換できるのですが、あくまで絵文字が一文字入ってくる前提に使えるものです。
コードの型情報に絵文字型を作るのも変だな、と感じたので、絵文字だけを確実に取り出せるものが欲しかったです。
静的な Markdown
ファイルの FrontMatter
に emoji:””という形で書いているが、ヒューマンエラーで" "
と入力してしまった場合にも対応できますね。
注意点
大量アクセスがある場合は、画像のミラーサイトやキャッシュをきちんと用意するべき、だと思います。
そういった仕組みを整えないと、CDN
とは言え、リクエストが増えすぎることとなり、迷惑がかかってしまいますね。
おわりに
サイトに絵文字を可愛らしく埋め込みましょう。