Quick Take

import { strict as assert } from "assert";
import { alts } from "html-img-alt";

// string-in, string-out:
  alts('zzz<img src="spacer.gif" >zzz'),
  'zzz<img src="spacer.gif" alt="" >zzz'


This program adds missing alt attributes to img tags and tweaks existing-ones:

  1. If alt attribute is missing on any img tag, it will add an one.
  2. If alt attribute is present on any img tag, it will run its contents through string-unfancy to:
    • decode all HTML entities, recursively (in case multiple HTML encoding was applied)
    • replace "fancy" characters with their simpler equivalents within ASCII range. For example, single curly quotes are changed into single apostrophes. This includes dashes and all sorts of double quotes.
    • replace all non-breaking spaces with regular spaces
  3. If img empty alt attribute has single quotes, it will be replaced with empty double-quotes.
  4. It will also normalise the white space within img tags, leaving one space between attributes and leaving one space before the closing slash (XHTML) or closing bracket (HTML).
  5. You can turn it off, but by default all the contents of the image ALT attributes will be trimmed and unfancie'd (curly quotes, m/n-dashes replaced with single quotes, minuses). That's to keep it simple for old email consumption software and make it easier to QA them.

html-img-alt works fine with both HTML and XHTML; it doesn't touch the closing slashes. Use a separate library for enforcing the closing slashes (or removing them) from singleton tags (br, hr and so on).

The main USP of this library is that it does not parse the HTML. It will never throw an error because of a dirty code. It might throw because of wrong input type, but not because of something in the code.


alts(str, [opts])

In other words, it's a function which takes two input arguments, second-one being optional (marked by square brackets).


options object's key Type Obligatory? Default Description
unfancyTheAltContents Boolean no true Are each image's alt attributes contents trimmed and processed by string-unfancy

Here are the defaults in one place for copying:

unfancyTheAltContents: true;

2020 summer update

At our today's understanding, alt attributes should be enforced via a linter, during coding. Think of prettier and eslint in web development.

The main consumer of this program - detergent - evolved greatly since and two reasons stop us from using this package:

Performance. Other tools will surely parse (or scanerless-way process) the HTML and another round of processing is both not DRY and perf-taxing

Reportability. All string (code) processing we do nowadays is done using ranges - composable records where we don't mutate string more than once in the whole program. This opens many opportunities for the next-generation web apps and JS packages.

For example, ranges allow Detergent.io opens in a new tab web app to show only toggles, applicable to the current input. The program not only processes the text, but even reports which of the options would not even make a difference for a given input. And UI uses that info to hide those toggles. That's the next-generation web applications we're talking about.


See it in the monorepo opens in a new tab, on GitHub.


To report bugs or request features or assistance, raise an issue on GitHub opens in a new tab.

Any code contributions welcome! All Pull Requests will be dealt promptly.


MIT opens in a new tab

Copyright © 2010–2021 Roy Revelt and other contributors

Related packages:

📦 emlint 5.0.1
Pluggable email template code linter
📦 html-crush 5.0.1
Minifies HTML/CSS: valid or broken, pure or mixed with other languages
📦 stristri 4.0.1
Extracts or deletes HTML, CSS, text and/or templating tags from string
📦 string-strip-html 9.0.1
Strips HTML tags from strings. No parser, accepts mixed sources
📦 detect-is-it-html-or-xhtml 5.0.1
Answers, is the string input string more an HTML or XHTML (or neither)
📦 detect-templating-language 3.0.1
Detects various templating languages present in string
📦 html-table-patcher 5.0.1
Visual helper to place templating code around table tags into correct places