Minify and bundle HTML, CSS, and JS as part of your Netlify deployment
Tags: webdev, productivity, tutorial, devops
Published: 2023-01-18 13:00:00


A convenience offered by Netlify is running tasks during and after a build. Tasks such as optimizing assets and injecting snippets are tasks you may only want to do once, just before you deploy a new version of a website. Netlify calls these postprocesing tasks.

There are cases where you may want to handle this type of task as part of your own build process. If you don't need it in your local dev environment, then why not defer to the platform?

This can simplify your build process. And also, you can still preview the result before it goes live, by viewing it in a preview deployment branch.

I will cover minifying the HTML, CSS, and JS of a statically generated website today. It does not matter what static site generator you use. You just need to specify the build command (usually a npm script) and the output folder.

## Configuration options - web interface versus configuration file

You can set this up through the web interface by going into the *Site Settings*. Go to **Site settings > Build & deploy > Post processing > Asset Optimization**.

<img src="https:///www.roboleary.net/assets/img/blog/2023-01-18-minify-html-css-js-netlify-build/asset-optimization-options-netlify-ui.jpg" alt="asset optimization options in netlify ui" width="1245" width="726" loading="lazy">

I will show you how to set this up through [Netlify's configuration file](https://docs.netlify.com/configure-builds/file-based-configuration/). I think being explicit with a configuration file that lives with your code can help to prevent some mistakes.

The configuration file is called *netlify.toml* and is normally stored in the root of your site repository. You can include a configuration file at multiple levels for special cases like monorepos. Settings specified in *netlify.toml* override any corresponding settings made through the web interface.

## Set up asset optimization through a configuration file

Netlify as a platform enables you to optimize assets (CSS, JS, images) through some `[build.processing.<asset-type>]` options e.g. `[build.processing.css]` for css-related options.

If you want to minify HTML, you need to install a plugin called [netlify-plugin-minify-html](https://www.npmjs.com/package/netlify-plugin-minify-html), as below.

```shell
# Add the plugin as a dev dependency
npm i -D netlify-plugin-minify-html
```

Before we get to the config, one word of caution regarding minifying HTML - be careful with collapsing whitespace! Collapsing whitespace inside elements can result in spaces being removed between inline elements that will result in some text being pushed together. Generally, it is safer to be conservative with this behaviour. There is a `conservativeCollapse` option offered by the plugin that will prevent this from happening.

First, I will create a *netlify.toml* and place it in the root directory of my project.

Below the build processing options for minifying CSS and JS are enabled. I also choose to tell the *Minify HTML plugin* to minify inline CSS and JS also.

```toml
[build]
    command = "pnpm build"
    publish = "_site"

[build.processing]
  skip_processing = false
[build.processing.css]
  minify = true
  bundle = false
[build.processing.js]
  minify = true
  bundle = false

# Config for the Netlify Build Plugin: netlify-plugin-minify-html
[[plugins]]
  package = "netlify-plugin-minify-html"

  # Specify which deploy contexts we'll minify HTML in.
  # Supports any Deploy Contexts available in Netlify.
  # https://docs.netlify.com/site-deploys/overview/#deploy-contexts
  [plugins.inputs]
    contexts = [
      'production',
      'branch-deploy',
      'deploy-preview'
    ]

  # Optionally, override the default options for the minification
  # https://github.com/kangax/html-minifier#options-quick-reference
  [plugins.inputs.minifierOptions]
    collapseWhitespace = true
    conservativeCollapse = true
    minifyCSS = true
    minifyJS = true
```

Also, you can choose to bundle CSS files or JS files through the `bundle` option. I have **bundling disabled above**.

If you want to optimize images, you can add the following option:

```toml
[build.processing.images]
  compress = true
```

I couldn't find any information on what optimization is performed on images. It seems strange that there is no related options, surely you would want more of a say on the optimization than trying it on or off?

For further information, you can read:
- The Netlify docs for their information on:
	- [The configuration file](https://docs.netlify.com/configure-builds/file-based-configuration/)
	- [The postprocessing tasks](https://docs.netlify.com/site-deploys/post-processing/)
- NPM docs for [netlify-plugin-minify-html](https://www.npmjs.com/package/netlify-plugin-minify-html) to learn about the plugin.