No 3rd party dependencies. All dependencies and devDependencies, checked recursively, are Codsen packages.
Permalink to InstallationInstallation
Permalink to Quick TakeQuick Take
Permalink to ExamplesExamples
- Ignores code tags and their contents
- A bypass callback and a do-nothing callback
- Strip an entire CDATA section
- Decode HTML entities before recognising and stripping encoded tags
- Keep a link destination next to its label
- Put a retained link destination on a new paragraph
- Extract HTML
<head>contents - Strip an HTML comment and prevent adjacent text from joining
- Preserve selected tags while stripping the rest
- Strip a JSX component tag from surrounding text
- Retain href and link label
- Leave only HTML
- Leave only opening
tdtags - Leave only
tdtags - Minimal example using Ranges
- Preserve indentation while collapsing whitespace around stripped tags
- Leave JSP scriptlets intact while stripping HTML
- Preserve punctuation around removed inline tags
- Preserve literal comparison brackets in plain text
- Insert spaces when removing tags between adjacent text
- Map progress reporting into a custom percentage range
- Remove all HTML from a string
- Strip script tags but retain their text when paired-content removal is disabled
- Strip HTML from a raw JSON string
- Remove a selected tag pair together with its contents
- Preserve custom elements while stripping recognised HTML tags
- Trim ordinary spaces while preserving tabs and line breaks
- Prevent widow words while preserving HTML
- Wrap a retained link destination with custom markers
Features
- Non-parsing, so works on HTML mixed with other languages.
- Non-parsing, so works on broken, partial, incomplete or non-valid HTML.
- Attempts to format the output nicely.
- Full control using a callback if needed.
- Can remove or ignore certain tag pairs along with their children tags.
- Can be used to generate Email Text versions —
hrefURLs can be retained. - Enabled-by-default but optional Recursive HTML Decoding — nothing will escape!
- It won’t strip templating tags (like JSP).
Quoted attribute values
A greater-than sign inside a closed single- or double-quoted attribute value does not end the tag. The complete attribute is removed with its tag:
stripHtml('<p title="prefix > hidden">visible</p>').result;
// → "visible"
The same boundary applies when inspecting tags through opts.cb: attribute values and tag positions cover the complete quoted value. Returned ranges retain their original UTF-16 offsets.
By default, character references are decoded before HTML is interpreted. Use skipHtmlDecoding: true when the original HTML must establish attribute boundaries before any text decoding:
stripHtml('<p title="">hidden">visible</p>', {
skipHtmlDecoding: true,
}).result;
// → "visible"
API — stripHtml()
The main function stripHtml() is imported like this:
It’s a function which takes two input arguments:
| Input argument | Type | Obligatory | Description |
|---|---|---|---|
inputType: String Obligatory: yes | |||
input | String | yes | Strip tags from this string. |
optsType: Plain object Obligatory: no | |||
opts | Plain object | no | Optional Options Object. |
The Optional Options Object has the following shape:
| Key | Type | Default | Description |
|---|---|---|---|
ignoreTagsType: Array of zero or more strings Default: [] | |||
ignoreTags | Array of zero or more strings | [] | These tags will not be removed |
onlyStripTagsType: Array of zero or more strings Default: [] | |||
onlyStripTags | Array of zero or more strings | [] | If one or more tag names are given here, only these tags will be stripped, nothing else |
ignoreTagsWithTheirContentsType: Array of zero or more strings Default: [] | |||
ignoreTagsWithTheirContents | Array of zero or more strings | [] | Opposite of stripTogetherWithTheirContents |
stripTogetherWithTheirContentsType: Array of zero or more strings, or something falsy Default: ['script', 'style', 'xml'] | |||
stripTogetherWithTheirContents | Array of zero or more strings, or something falsy | ['script', 'style', 'xml'] | These tags will be removed along with their children tags. Set it to something falsy to turn it off. You can set it to ["*"] to strip all tags this way. |
skipHtmlDecodingType: Boolean Default: false | |||
skipHtmlDecoding | Boolean | false | By default, all HTML entities for example < will be recursively decoded before HTML-stripping. You can turn it off here if you don’t need it and gain performance. |
trimOnlySpacesType: Boolean Default: false | |||
trimOnlySpaces | Boolean | false | It ensures non-spaces are not trimmed from the outer edges of a string. It’s used when multiple strings are stripped from tags and then concatenated. |
stripRecognisedHTMLOnlyType: Boolean Default: false | |||
stripRecognisedHTMLOnly | Boolean | false | If the input has templating language tags, and you wish to retain them, enable this setting. |
dumpLinkHrefsNearbyType: Plain object or something falsy Default: false | |||
dumpLinkHrefsNearby | Plain object or something falsy | false | Used to customise the output of link URL’s: to enable the feature, also customise the URL location and wrapping. |
cbType: Something falsy or a function Default: null | |||
cb | Something falsy or a function | null | Gives you full control of the output and lets you tweak it. See the dedicated chapter below. |
Here are all defaults in one place for copying:
The function will return a plain object:
| Key | Type | Description |
|---|---|---|
logType: Plain object | ||
log | Plain object | For example, { timeTakenInMilliseconds: 6 } |
resultType: String | ||
result | String | The string output where all ranges were applied to it. |
rangesType: Ranges or null | ||
ranges | Ranges or null | For example, if characters from index 0 to 5 and 30 to 35 were deleted, that would be [[0, 5], [30, 35]]. Another example, if nothing was found, it would put here null. |
allTagLocationsType: Array of zero or more arrays | ||
allTagLocations | Array of zero or more arrays | For example, [[0, 5], [30, 35]]. If you String.slice() each pair, you’ll get HTML tag values. |
filteredTagLocationsType: Array of zero or more arrays | ||
filteredTagLocations | Array of zero or more arrays | Only the tags that ended up stripped will be reported here. Takes into account opts.ignoreTags and opts.onlyStripTags, unlike allTagLocations above. For example, [[0, 5], [30, 35]]. |
Using Ranges from the output
The ranges from the output are compatible with range-ecosystem libraries, see example. Behind the scenes, this program actually operates on Ranges.
opts.trimOnlySpaces
Hi →Hi instead ofHi →Hi
The trailing whitespace can be rogue but it can be intentional. It’s like shreds in jeans. So, to mark the intention, people use non-breaking spaces around the string. Also in this context, line breaks, tabs and other whitespace characters are concerned too.
When this setting is turned on, only spaces will be trimmed from outside; an algorithm will stop at a first non-space character, in this case, non-breaking space:
" Hi! Please <div>shop now</div>! "
is turned into:
" Hi! Please shop now! "
This setting is disabled by default.
opts.dumpLinkHrefsNearby
The purpose of this option is to retain link URLs:
Watch both <a href="https://www.cnn.com" target="_blank">CNN</a> and <a href="https://www.bbc.co.uk" target="_blank">BBC</a>.
could be turned into:
Watch both CNN https://www.cnn.com and BBC https://www.bbc.co.uk.
The opts.dumpLinkHrefsNearby value is a plain object, for example:
| Key | Default | Description |
|---|---|---|
enabledDefault: false | ||
enabled | false | By default, this function is disabled — URL’s are not inserted nearby. Set it to Boolean true to enable it. |
putOnNewLineDefault: false | ||
putOnNewLine | false | By default, URL is inserted after any whatever was left after stripping the particular linked piece of code. If you want, you can force all inserted URL’s to be on a new line, separated by a blank line. |
wrapHeadsDefault: "" | ||
wrapHeads | "" | This string (default is an empty string) will be inserted in front of every URL. Set it to any string you want, for example [. |
wrapTailsDefault: "" | ||
wrapTails | "" | This string (default is an empty string) will be inserted straight after every URL. Set it to any string you want, for example ]. |
This feature is aimed at producing Text versions for promotional or transactional email campaigns.
But equally, any link on any tag, even one without text, will be retained:
Codsen
<div>
<a href="https://codsen.com" target="_blank"><img src="logo.png" width="100" height="100" border="0" style="display:block;" alt="Codsen logo" /></a>
</div>
it’s turned into:
Codsen https://codsen.com
This setting is disabled by default.
opts.stripTogetherWithTheirContents
This setting is enabled by default and strips the exact tag names ['script', 'style', 'xml'] along with all their contents.
Use exact tag names in this option. The only supported wildcard is the exact entry "*". Set the option to ["*"] to strip every paired tag along with its contents.
opts.cb
Use opts.cb to decide which proposed ranges to apply. For example, you can accept ranges only for selected tags or inspect tags which ignoreTags retains.
Pass a callback function as opts.cb. When a callback is present, the program does not add its per-event proposals automatically. Inspect tag and proposedReturn, then push each range that you want to apply into rangesArr. If you do not push a proposal, that callback event does not change the output.
const cb = ({ tag, rangesArr, proposedReturn }) => {
if (tag) {
// Inspect the current tag.
console.log(JSON.stringify(tag, null, 4));
}
// Accept this callback event's proposed range.
if (proposedReturn) {
rangesArr.push(...proposedReturn);
}
};
const { result } = stripHtml("abc<hr>def", { cb });
console.log(result);
The tag key contains parser metadata collected for the current tag candidate. Log it when you need to inspect the available fields.
cb() example
The callback receives a range proposal for each detected tag candidate. Push that proposal to rangesArr to accept it, change it before pushing, or omit it.
The forwarding callback example pushes each non-null proposedReturn. This accepts every per-event proposal. Calls that omit cb also apply automatic final whitespace cleanup, so outer whitespace can differ.
From here, you can add more logic, conditionally push only certain ranges, tweak the ranges that get pushed and so on.
The tag key contains all the info program has gathered for currently stripped tag, it looks like this:
{
"attributes": [],
"slashPresent": false,
"leftOuterWhitespace": 3,
"onlyPlausible": false,
"nameStarts": 4,
"nameContainsLetters": true,
"nameEnds": 6,
"name": "hr",
"lastOpeningBracketAt": 3,
"lastClosingBracketAt": 6
}
For example, strict bracket-to-bracket range would be [tag.lastOpeningBracketAt, tag.lastClosingBracketAt + 1].
API — defaults
You can import defaults:
It's a plain object:
The main function calculates the options to be used by merging the options you passed with these defaults.
API — version
You can import version:
API — types
This package is written in TypeScript and exports the following types:
| Type | Description |
|---|---|
OptsType: Opts | |
Opts | The Optional Options Object of stripHtml(), documented above. |
ResType: Res | |
Res | What stripHtml() returns — the result, the ranges, the tag locations and a log. |
CbObjType: CbObj | |
CbObj | What opts.cb is called with — the tag, the proposed deletion range and the ranges gathered so far. |
TagType: Tag | |
Tag | One recognised tag: its name, bracket positions and attributes. |
AttributeType: Attribute | |
Attribute | One attribute on a Tag — where its name and value each start and end. |
import type { Attribute, CbObj, Opts, Res, Tag } from "string-strip-html";
Algorithm
Speaking scientifically, it works at lexer level — it’s a non-parsing, single-pass character scanner.
In simple language, this program does not use parsing and AST trees. It processes the input string as text. Whatever the algorithm doesn’t understand — errors, broken code, non-HTML, etc. — it skips.