Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

prevOpen Source→html-entities-not-email-friendlynext

html-entities-not-email-friendly0.10.0

All HTML entities which are not email template friendly

Downloads per monthChangelogMIT Licenselibera manifesto
  • the top
  • Installation
  • Quick Take
  • Examples
  • PURPOSE
  • API
  • API — TYPES
  • NOTEMAILFRIEN…
  • NOTEMAILFRIEN…
  • NOTEMAILFRIEN…
  • NOTEMAILFRIEN…
  • IN PRACTICE
  • Changelog

Installation

Quick Take

Examples

  • Inspect the number of known unsafe named entities
  • Skip impossible entity-name lengths before consulting the sets
  • Check entity names case-insensitively with the lowercase set
  • Look up a safer replacement for a named entity

Purpose

Unlike Web pages, Email templates are sent over SMTP and need to be HTML-encoded.

HTML encoding can be done three ways: decimal (£), hexadecimal (£) and named forms (£).

The named entities can be memorised or recognised more easily than numeric-ones. When you check the template’s text, £ is more informative than £. If somebody mistakenly put ¤ you would not tell easily, but &pund; stands out instantly!

The only problem is, not all named entities are supported well across all email clients, in particular, in Windows desktop Outlooks.

This package tells which entities exactly and not supported widely and tells you what to convert them to.

This program exports few different lists:

  • notEmailFriendly — a plain object, key value pairs are like AMP: "amp" — total keys: 1841
  • notEmailFriendlySetOnly — a Setopens in a new tab of only entity names (in correct letter case) — total size: 1841
  • notEmailFriendlyLowercaseSetOnly — an alphabetically sorted Setopens in a new tab of lowercase entity names — total size: 1534

API

This package has five exports:

  • notEmailFriendly
  • notEmailFriendlySetOnly
  • notEmailFriendlyLowercaseSetOnly
  • notEmailFriendlyMinLength
  • notEmailFriendlyMaxLength
Key’s nameKey’s value’s typePurpose
notEmailFriendly
notEmailFriendlyplain objectPlain object of all named HTML entities. The key is an entity’s name; value is a raw decoded entity. 1841 in total.
notEmailFriendlySetOnly
notEmailFriendlySetOnlysetA set of all entity names, in correct case, unsorted. 1841 in total.
notEmailFriendlyLowercaseSetOnly
notEmailFriendlyLowercaseSetOnlysetA set of all entity names, in lowercase, sorted. 1534 in total (because the set holds both AMP and amp, for example).
notEmailFriendlyMinLength
notEmailFriendlyMinLengthnatural numberthe string length of the shortest of all entities, currently hardcoded to 2
notEmailFriendlyMaxLength
notEmailFriendlyMaxLengthnatural numberthe string length of the longest of all entities, currently hardcoded to 31

API — types

This package is written in TypeScript and exports the type Obj — a plain object with string keys and values of any type — the shape of the exported notEmailFriendly mapping.

import type { Obj } from "html-entities-not-email-friendly";

notEmailFriendly

import { notEmailFriendly } from "html-entities-not-email-friendly";
// it's a plain object of key-value pairs where key is entity name, value is
// decoded numeric entity analogue of it
console.log(Object.keys(notEmailFriendly).length);
// => 1841

The point of plain object notEmailFriendly is to decode the entities.

For example, among the keys you can see:

And: "#x2A53",

This means, named HTML entity ⩓ is not email friendly and should be put as ⩓.

As you noticed, ampersands and semicolons are missing in keys and values (but they’re obligatory in HTML code so add them yourself).

notEmailFriendlySetOnly

Setsopens in a new tab are awesome because they’re fast.

When you import notEmailFriendlySetOnly, it’s a Set of only the key names:

import { notEmailFriendlySetOnly } from "html-entities-not-email-friendly";
for (const entityName of notEmailFriendlySetOnly) {
  console.log(entityName);
}
// => "AMP",
//    "Abreve",
//    ...

// another example: check is given entity a valid HTML named entity string?
console.log(notEmailFriendlySetOnly.has("tralala"));
// => false - no "tralala" (if put fully, &tralala;) is not a recognised named HTML entity's name

console.log(notEmailFriendlySetOnly.has("Aogon"));
// => true - yes "Aogon" (if put fully, Ą) is a recognised named HTML entity's name

You must use Set methods: has, size etc on notEmailFriendlySetOnly. It’s not an array, it’s a set.

notEmailFriendlyLowercaseSetOnly

notEmailFriendlyLowercaseSetOnly is also a Set but all values are lowercase and sorted.

The idea is that if you have a named HTML entity and suspect that its letter case might be messed up, you lowercase it and match against this Set. Now, if something is found, do actions matching against plain object keys in notEmailFriendly (aiming to decode to numeric entities), OR matching against a Set with exact case, notEmailFriendlySetOnly (if value is not found, letter case in your entity is messed up).

import { notEmailFriendlySetOnly } from "html-entities-not-email-friendly";
for (const entityName of notEmailFriendlySetOnly) {
  console.log(entityName);
}
// => "AMP",
//    "Abreve",
//    ...

notEmailFriendlyMinLength and notEmailFriendlyMaxLength

Their point is to give you guidance how long or short entities can be:

import { notEmailFriendlyMinLength, notEmailFriendlyMaxLength } from "html-entities-not-email-friendly";
console.log(`The shortest length in the set is: ${notEmailFriendlyMinLength} and longest is ${notEmailFriendlyMaxLength}.`);
// => The shortest length in the set is: 2 and longest is 31.

Keep in mind, length here does not count ampersand and semicolon. For example, Abreve length is 6 characters but in the HTML, it is 8: Ă,

In practice

This program allows detergent to automatically switch between named and numeric HTML entities, prioritising on named, if they’re supported (according to this program).

Detergent’s competitor, Email on Acid Character Converteropens in a new tab only uses numeric entities. Not to mention, EoA Character Converter ignores invisible characters, which is a liability.

Changelog

Open Changelog
↑ back to top
prev next

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab