Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript detect if native emoji is supported

I would like to detect if native emoji is supported.
Only if it does not, I will then load emoji font to save bandwidth and also make the application look more native.

However, as I search through the Internet, I only found someone using userAgent to check if emoji is supported or not.
For example, the below code is from https://github.com/github/g-emoji-element/blob/master/emoji-detection.js,

export function isEmojiSupported(): boolean {
  const onWindows7 = /\bWindows NT 6.1\b/.test(navigator.userAgent)
  const onWindows8 = /\bWindows NT 6.2\b/.test(navigator.userAgent)
  const onWindows81 = /\bWindows NT 6.3\b/.test(navigator.userAgent)
  const onFreeBSD = /\bFreeBSD\b/.test(navigator.userAgent)
  const onLinux = /\bLinux\b/.test(navigator.userAgent)

  return !(onWindows7 || onWindows8 || onWindows81 || onLinux || onFreeBSD)
}

Though the regular expression may not be perfect, as Firefox in Windows 7 does support Emoji as from http://caniemoji.com/.

However, as different browser or libraries may have different set of emoji, some emoji may render perfectly in one browser, and some just not render very well.

So is there a better method other than using userAgent to check if Emoji is supported?

like image 330
CHANist Avatar asked Sep 18 '25 13:09

CHANist


2 Answers

There used to be a technique to measure the width of an element containing text in 2 different fonts to see if a font is supported by seeing if a fallback font was used.

A similar technique can be used with emojis by taking advantage of emoji sequences that collapse onto a single emoji.

If a browser supports emojis it will render 1 glyph for emojis that are made up of 2 sequences. If it doesn't, it will render 2 glyphs.

var trinidad = String.fromCodePoint(0x1F1F9, 0x1F1F9);
var hammerpick = String.fromCodePoint(0x2692);

function getWidth(s) {
  var n = document.body.appendChild(document.createElement("span"));
  n.appendChild(document.createTextNode(s));
  var w = n.offsetWidth;
  n.parentNode.removeChild(n);
  return w;
}

console.log(getWidth(trinidad) === getWidth(hammerpick) ? "supported": "not supported");
like image 123
Kernel James Avatar answered Sep 20 '25 04:09

Kernel James


Rather than trying to detect, I would suggest loading the font with all the glyphs you want, and using font-display: swap in your CSS.

Then, your page can still be shown while the loading of this extra font is still occurring.

See also: https://css-tricks.com/font-display-masses/

like image 20
Brad Avatar answered Sep 20 '25 04:09

Brad