# astro-html-minifier-next

> Minify [Astro][astro] HTML assets using [html-minifier-next][html-minifier-next]!

- **Improves page speed** - Reduces the size of HTML assets by removing everything unnecessary.
- **Highly configurable** - All options from [html-minifier-next][html-minifier-next] are supported and can be customized.
- **Fast** - Runs the minification of all assets with (limited) concurrency and [Lightning CSS][lightningcss].

[![Version badge](https://img.shields.io/npm/v/astro-html-minifier-next?style=for-the-badge&label=Version&labelColor=2a2d35&color=f2ebf4)][latest-release]
[![NPM downloads badge](https://img.shields.io/npm/d18m/astro-html-minifier-next?style=for-the-badge&label=NPM%20Downloads&labelColor=2a2d35&color=e13fa0&cacheSeconds=86400)][package-on-npm]
[![JSR score badge](https://jsr.io/badges/@jonasgeiler/astro-html-minifier-next/score?style=for-the-badge&label=Score&logoColor=fff&labelColor=2a2d35&color=f2ebf4&cacheSeconds=86400)][package-on-jsr]
[![NPM unpacked size badge](https://img.shields.io/npm/unpacked-size/astro-html-minifier-next?style=for-the-badge&labelColor=2a2d35&color=e13fa0)][package-on-bundlejs]

```typescript
import { defineConfig } from "astro/config";
import htmlMinifier from "astro-html-minifier-next";

export default defineConfig({
  integrations: [
    htmlMinifier({
      /* My recommended html-minifier-next options: */
      caseSensitive: true,
      collapseAttributeWhitespace: false,
      collapseBooleanAttributes: true,
      collapseInlineTagWhitespace: false,
      collapseWhitespace: true,
      conservativeCollapse: false,
      continueOnMinifyError: false,
      continueOnParseError: false,
      decodeEntities: true,
      includeAutoGeneratedTags: true,
      keepClosingSlash: false,
      minifyCSS: true,
      minifyJS: true,
      minifySVG: true,
      minifyURLs: false,
      noNewlinesBeforeTagClose: false,
      preserveLineBreaks: false,
      preventAttributesEscaping: false,
      processConditionalComments: false,
      removeAttributeQuotes: false, // Technically they are optional and can greatly reduce size, but the HTML specification recommends always using quotes.
      removeComments: true,
      removeEmptyAttributes: true,
      removeEmptyElements: false,
      removeOptionalTags: false,
      removeRedundantAttributes: true,
      removeScriptTypeAttributes: true,
      removeStyleLinkTypeAttributes: true,
      removeTagWhitespace: false,
      sortAttributes: false,
      sortClassNames: false,
      useShortDoctype: true,
    }),
  ],
});
```

## Installation

Add the integration to your Astro project using the `astro add` command.  
This will install the package and make the appropriate changes to your
`astro.config.mjs`/`astro.config.ts` file in one step:
```bash
npx astro add astro-html-minifier-next
```
If you prefer to add the integration manually instead, complete the
following two steps:
1. Install the package to your project’s dependencies using your preferred
   package manager.  
   If you’re using npm or aren’t sure, run this in the terminal:
   ```bash
   npm install --save-dev astro-html-minifier-next
   ```
   Or, if you're using Deno, run this in the terminal:
   ```bash
   deno add jsr:@jonasgeiler/astro-html-minifier-next
   ```
2. Add the integration to your `astro.config.mjs`/`astro.config.ts` file:
   ```typescript
   import { defineConfig } from "astro/config";
   
   // ADD THE FOLLOWING LINE:
   import htmlMinifier from "astro-html-minifier-next";

   export default defineConfig({
     // ...
   
     integrations: [
       // ...
   
       // ADD THE FOLLOWING LINE:
       htmlMinifier({ /* Your html-minifier-next options here. */ }),
     ],
   });
   ```

## Usage

Once installed, the integration will automatically minify all HTML assets
generated by Astro during the build process using the provided
[html-minifier-next][html-minifier-next] options.

### Options

You can find a quick reference of all available options in the
[html-minifier-next documentation][html-minifier-next-options].  
You can also check out the
[JSDoc comments in the source code][html-minifier-next-options-source].

There is currently one additional option only specific to this Astro
integration. [See below](#alwayswriteminifiedhtml).

> **Tip**  
> To ensure consistent and wide browser support throughout your project,
> I recommend setting the `targets` property of the `minifyCSS` option to your
> project's [Browserslist][browserslist] query.
> This configures [Lightning CSS][lightningcss] (the CSS minifier used by
> [html-minifier-next][html-minifier-next]) to properly optimize the CSS
> according to the browsers you want to support.
> 
> You can do this, by adding the following lines to your
> `astro.config.mjs`/`astro.config.ts` file:
> ```typescript
> import { defineConfig } from "astro/config";
> import htmlMinifier from "astro-html-minifier-next";
> 
> // ADD THE FOLLOWING LINES:
> import browserslist from "browserslist";
> import { browserslistToTargets } from "lightningcss";
> 
> export default defineConfig({
>   // ...
> 
>   integrations: [
>     // ...
> 
>     htmlMinifier({
>       // ...
> 
>       minifyCSS: {
>         // ...
> 
>         // ADD THE FOLLOWING LINE:
>         targets: browserslistToTargets(browserslist("defaults")),
>       },
>     }),
>   ],
> });
> ```
> 
> More information can be found in the [Lightning CSS documentation][lightningcss-docs].

#### `alwaysWriteMinifiedHTML`

This option is not passed to [html-minifier-next][html-minifier-next]. It
only controls the behavior of this Astro integration.

By default, the integration only overwrites the original HTML assets
if the minified HTML is smaller.
However, there are [cases][issue-7] where you might actually prefer the
larger output due to special compatibility reasons or otherwise.  
Setting this option to `true` causes the integration to always overwrite
the HTML assets with their minified results, regardless of size.

## Credits

This project wouldn't be possible without the awesome work of
[Juriy Zaytsev aka. @kangax][@kangax] ([html-minifier][html-minifier]),
[the Terser team][@terser] ([html-minifier-terser][html-minifier-terser]), and
of course [Jens Oliver Meiert aka. @j9t][@j9t] ([html-minifier-next][html-minifier-next]).

[astro]: https://astro.build/
[html-minifier-next]: https://www.npmjs.com/package/html-minifier-next
[html-minifier-next-options]: https://www.npmjs.com/package/html-minifier-next#options-quick-reference
[html-minifier-next-options-source]: https://github.com/j9t/html-minifier-next/blob/e2995fc35a7a3906d3d1960d508d0d24a02128c8/src/htmlminifier.js#L1501
[latest-release]: https://github.com/jonasgeiler/astro-html-minifier-next/releases/latest
[package-on-bundlejs]: https://bundlejs.com/?q=astro-html-minifier-next&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22lightningcss%22%5D%7D%7D
[package-on-jsr]: https://jsr.io/@jonasgeiler/astro-html-minifier-next
[package-on-npm]: https://www.npmjs.com/package/astro-html-minifier-next
[browserslist]: https://browsersl.ist/
[lightningcss]: https://lightningcss.dev/
[lightningcss-docs]: https://lightningcss.dev/docs.html#with-vite
[issue-7]: https://github.com/jonasgeiler/astro-html-minifier-next/issues/7
[@kangax]: https://github.com/kangax
[html-minifier]: https://github.com/kangax/html-minifier
[@terser]: https://github.com/terser
[html-minifier-terser]: https://github.com/terser/html-minifier-terser
[@j9t]: https://github.com/j9t
