Permalink to InstallationInstallation
Permalink to Quick TakeQuick Take
Permalink to ExamplesExamples
- Configure CSS comment removal
- Insert line breaks before selected tokens
- Treat a custom element as inline
- Choose which HTML comments to remove
- Wrap minified HTML at a line-length limit
- Observe progress in a custom interval
- Remove line indentations
- Remove HTML line breaks
- Inspect result metadata and edit ranges
Purpose
html-crush minifies mixed HTML and CSS, with a focus on email templates. It
scans the input without parsing it into an abstract syntax tree, so it can work
with incomplete markup and templates that contain Nunjucks, JSP, ESP, CDATA,
or other embedded languages.
Email HTML needs controls that general web-page minifiers do not always provide. For example, you can preserve Outlook conditional comments and place line breaks before selected tokens to keep generated lines within an email transport limit.
The scanner preserves ordinary quoted attribute values, CSS strings, and the
contents of script, pre, code, and textarea elements. HTML element names
are matched case-insensitively.
API — crush()
The main function crush() is imported like this:
Pass the HTML source as a string and, optionally, an options object or null:
function crush(str: string, opts?: InputOpts | null): Res;
InputOpts has the following shape. Every property is optional:
interface InputOpts {
lineLengthLimit?: number;
removeIndentations?: boolean;
removeLineBreaks?: boolean;
removeHTMLComments?: boolean | 0 | 1 | 2;
removeCSSComments?: boolean;
reportProgressFunc?: null | false | 0 | ((percentage: number) => void);
reportProgressFuncFrom?: number;
reportProgressFuncTo?: number;
breakToTheLeftOf?: string[] | null | false;
mindTheInlineTags?: string[];
}
| Key | Input type | Default | Description |
|---|---|---|---|
lineLengthLimitDefault: 500 | |||
lineLengthLimit | number | 500 | Sets the preferred maximum line length when removeLineBreaks is enabled. |
removeIndentationsDefault: true | |||
removeIndentations | boolean | true | Removes indentation while retaining line breaks. Enabling removeLineBreaks also enables this behavior. |
removeLineBreaksDefault: false | |||
removeLineBreaks | boolean | false | Removes existing line breaks, subject to lineLengthLimit and breakToTheLeftOf. |
removeHTMLCommentsDefault: false | |||
removeHTMLComments | boolean | 0 | 1 | 2 | false | false or 0 keeps comments. true or 1 removes ordinary comments but preserves Outlook conditionals. 2 removes all recognized HTML comments, including conditionals. |
removeCSSCommentsDefault: true | |||
removeCSSComments | boolean | true | Removes recognized CSS comments in style elements and quoted style attributes. Comment-like text inside CSS strings is preserved. |
reportProgressFuncDefault: null | |||
reportProgressFunc | Function or null, false, or 0 | null | Receives integer progress values for sufficiently large inputs. See Progress reporting. |
reportProgressFuncFromDefault: 0 | |||
reportProgressFuncFrom | number | 0 | Sets the beginning of the reported progress interval. |
reportProgressFuncToDefault: 100 | |||
reportProgressFuncTo | number | 100 | Sets the end of the reported progress interval. |
breakToTheLeftOfDefault: See below | |||
breakToTheLeftOf | string[] | null | false | See below | Starts a new line before a matching token when removeLineBreaks is enabled. Pass false, null, or an empty array to disable the defaults. |
mindTheInlineTagsDefault: See below | |||
mindTheInlineTags | string[] | See below | Lists inline element names whose surrounding whitespace needs extra protection. |
Here are all defaults in one place for copying:
The function returns a plain Res object:
type Range =
| [from: number, to: number]
| [from: number, to: number, whatToInsert: string | null | undefined];
interface Res {
log: {
timeTakenInMilliseconds: number;
originalLength: number;
cleanedLength: number;
bytesSaved: number;
percentageReducedOfOriginal: number;
originalLengthInCodeUnits: number;
cleanedLengthInCodeUnits: number;
codeUnitsSaved: number;
percentageReducedOfOriginalInCodeUnits: number;
originalLengthInUtf8Bytes: number;
cleanedLengthInUtf8Bytes: number;
utf8BytesSaved: number;
percentageReducedOfOriginalInUtf8Bytes: number;
};
applicableOpts: {
removeHTMLComments: boolean;
removeCSSComments: boolean;
};
ranges: Range[] | null;
result: string;
}
| Key | Description |
|---|---|
result | |
result | The minified HTML string. |
ranges | |
ranges | The edits in ranges notation, or null when no edit is needed. |
applicableOpts | |
applicableOpts | Reports whether the input contains removable HTML or CSS comments, independently of the current removal settings. |
log | |
log | Contains elapsed time and size statistics. |
The result contains only plain objects, arrays, strings, numbers, booleans, and
null. It can be serialized as JSON or sent through postMessage().
Size and timing fields
JavaScript string lengths count UTF-16 code units, not bytes. The explicit fields distinguish those lengths from the UTF-8 size that an encoded email would occupy. Percentages are rounded to the nearest integer.
log field | Meaning |
|---|---|
timeTakenInMilliseconds | |
timeTakenInMilliseconds | Best-effort elapsed time. Do not use it for exact comparisons. |
originalLength | |
originalLength | Legacy input length in UTF-16 code units. |
cleanedLength | |
cleanedLength | Legacy output length in UTF-16 code units. |
bytesSaved | |
bytesSaved | Legacy name for UTF-16 code units saved. This field does not contain a byte count. |
percentageReducedOfOriginal | |
percentageReducedOfOriginal | Legacy reduction percentage calculated from UTF-16 code units. |
originalLengthInCodeUnits | |
originalLengthInCodeUnits | Input length in UTF-16 code units. |
cleanedLengthInCodeUnits | |
cleanedLengthInCodeUnits | Output length in UTF-16 code units. |
codeUnitsSaved | |
codeUnitsSaved | Number of UTF-16 code units removed. |
percentageReducedOfOriginalInCodeUnits | |
percentageReducedOfOriginalInCodeUnits | Reduction percentage calculated from UTF-16 code units. |
originalLengthInUtf8Bytes | |
originalLengthInUtf8Bytes | Input size in UTF-8 bytes. |
cleanedLengthInUtf8Bytes | |
cleanedLengthInUtf8Bytes | Output size in UTF-8 bytes. |
utf8BytesSaved | |
utf8BytesSaved | Number of UTF-8 bytes removed. |
percentageReducedOfOriginalInUtf8Bytes | |
percentageReducedOfOriginalInUtf8Bytes | Reduction percentage calculated from UTF-8 bytes. |
For compatibility, the four legacy size fields keep their existing UTF-16 code-unit meaning. Use the explicit fields in new integrations.
Progress reporting
Use reportProgressFunc when crush() runs in a Web Worker or another UI that
needs completion feedback. Inputs of 1,000 code units or fewer do not call the
callback. Inputs from 1,001 through 1,999 code units report a midpoint and
completion. Longer inputs report incremental values.
Every reported value is an integer within the interval configured by
reportProgressFuncFrom and reportProgressFuncTo. Both changed and unchanged
inputs finish at the configured ending value. The callback is observational:
it does not change the result, ranges, or deterministic statistics.
import { crush } from "html-crush";
const res = crush(source, {
removeLineBreaks: true,
reportProgressFunc: (percentage) => {
postMessage({ type: "progress", percentage });
},
});
postMessage({ type: "result", res });
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 these public types:
| Type | Description |
|---|---|
InputOptsType: InputOpts | |
InputOpts | The optional input accepted by crush(), including the supported disabling sentinels. |
OptsType: Opts | |
Opts | The fully resolved internal option shape after defaults and input normalization. |
ResType: Res | |
Res | The minified result, edit ranges, applicability report, and completion statistics. |
import type { InputOpts, Opts, Res } from "html-crush";