# html-asset-hasher

[![builds.sr.ht status](https://builds.sr.ht/~quaff/html-asset-hasher.svg)](https://builds.sr.ht/~quaff/html-asset-hasher)
[![license](https://img.shields.io/crates/l/html-asset-hasher)](https://git.sr.ht/~quaff/html-asset-hasher/blob/main/LICENSE)
[![Crates.io Version](https://img.shields.io/crates/v/html-asset-hasher)](https://crates.io/crates/html-asset-hasher)
[![Crates.io Total Downloads](https://img.shields.io/crates/d/html-asset-hasher)](https://crates.io/crates/html-asset-hasher)
[![irc channel](https://img.shields.io/badge/irc.libera.chat-%23hah-purple)](ircs://irc.libera.chat/#hah)
[![Mastodon Follow](https://img.shields.io/mastodon/follow/137584?style=flat)](https://mastodon.social/@quaff)

Asset cache busting for your static HTML files, with optional [Tailwind CSS][tailwind-css]
bundling!

[summary](https://sr.ht/~quaff/html-asset-hasher)
[source](https://git.sr.ht/~quaff/html-asset-hasher)
[mailing lists](https://sr.ht/~quaff/html-asset-hasher/lists)
[tickets](https://todo.sr.ht/~quaff/html-asset-hasher)

## Getting started

### Requirements

- `cargo`
- `tailwindcss` (optional)

#### Tailwind CSS support (optional)

Refer to the [Tailwind CSS documentation][tailwind-css-config] for configuration
details. If Tailwind CSS isn't installed, the `tailwindcss` binary will be
downloaded and used to generate the CSS.

### Installation

With `cargo`:

```shell
cargo install html-asset-hasher
```

Building from git:

```shell
cargo install --git https://git.sr.ht/~quaff/html-asset-hasher
```

With [cargo-binstall][cargo-binstall]:

```shell
cargo binstall html-asset-hasher
```

_Note: Currently, only supports Linux; For improved build times in your CI/CD
pipelines._

## How it works

`html-asset-hasher` currently supports `<img>`, `<link>` and `<script>` tags for
images, stylesheets and scripts. It also offers [Subresource Integrity (SRI)][subresource-integrity]
support.

Inspired by [Trunk][trunkrs], `html-asset-hasher` looks for `data-hasher`,
`data-file` and `data-url` attributes on `<img>`, `<link>` and `<script>` tags:

- **`data-hasher`**: A flag attribute that indicates the tag should be parsed.
- **`data-file`**: Specifies the relative path to the asset you want to hash.
- **`data-url`**: Specifies the URL you want to download and hash.

_Note: if both are present, `data-url` will take precedence over `data-file`._

That's it! These few attributes are all you need to enable cache busting.

Once you're ready, run `html-asset-hasher` against your static HTML file. By
default, the generated files will be output to the `dist/` directory in your root
working directory.

### Usage

```shell
Usage: html-asset-hasher [OPTIONS] [PATHS]...

Arguments:
  [PATHS]...  Input HTML files or directories

Options:
  -o, --output <DIR>                         Output directory [default: dist]
  -s, --sha2-hash <SHA2_HASH>                SHA2 Hash algorithm [default: sha384]
  -t, --tailwind-version <TAILWIND_VERSION>  TailwindCSS version to download [default: 4.1.17]
      --debug                                Turn debugging information on
  -h, --help                                 Print help
  -V, --version                              Print version
```

### Example

Here’s an example of how to use `html-asset-hasher` in an HTML file (`index.html`):

```html
<link data-hasher data-file="assets/favicon.ico" rel="icon" />
<link data-hasher data-file="src/styles/tailwind.css" rel="tailwind-css" />
<link data-hasher data-url="https://example.com/main.css" rel="stylesheet" />
<script
  data-hasher
  data-file="src/scripts/main.js"
  type="text/javascript"
></script>
<img data-hasher data-url="https://example.com/image.png" alt="example image" />
```

To process the file, run:

```shell
html-asset-hasher index.html
```

The generated HTML will be saved to `dist/index.html`, and it will look
something like this:

```html
<link
  rel="icon"
  href="favicon.iLfWPvSXyJusY1MS4bh2Gg-Eq5FzRNNFH2qBtptWOJ30c8AYPl5L7aR1dKtwp_no.ico"
/>
<link
  rel="stylesheet"
  href="tailwind.COunCCmPUZVOsiyGCRp7tDQxoo3jOzAScLezMwB8ygZPmPJCZHuLypHXRUbusv0N.css"
  integrity="sha384-COunCCmPUZVOsiyGCRp7tDQxoo3jOzAScLezMwB8ygZPmPJCZHuLypHXRUbusv0N"
/>
<link
  rel="stylesheet"
  href="main.E1QXOJQvt1C-Cewy5WvqKozszqqDMGydV4TeOw3lEoJS1xClsbKBBWyCFKMDi34V.css"
  integrity="sha384-E1QXOJQvt1C+Cewy5WvqKozszqqDMGydV4TeOw3lEoJS1xClsbKBBWyCFKMDi34V"
/>
<script
  src="main.1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs_HgeFs.js"
  integrity="sha384-1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs+HgeFs"
  crossorigin="anonymous"
></script>
<img
  src="image.e1QXOJQvt1C+Cewy5WvqKozszqqDMGydV4TeOw3lEoJS1xClsbKBBWyCFKMDi34V.png"
  alt="example image"
/>
```

For a full working demo, check out the [code for my website][quaff-site-repo].

## Contributing

To contribute to `html-asset-hasher`, you'll need `npm` on your system, install
`nodejs-18` or higher with your package manager of choice.

Next, run the following script in the root of the repository to install the
necessary Git hooks along with [commitlint][commitlint]:

```shell
./contributing.sh
```

These hooks will ensure that your commits adhere to project standards.

For more information on commit conventions, refer to the [Conventional Commits][conventional-commits]
guidelines.

[tailwind-css]: https://tailwindcss.com/
[tailwind-css-config]: https://tailwindcss.com/docs/configuration
[subresource-integrity]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
[trunkrs]: https://trunkrs.dev
[quaff-site-repo]: https://git.sr.ht/~quaff/quaff.site
[conventional-commits]: https://www.conventionalcommits.org/en/v1.0.0
[commitlint]: https://commitlint.js.org/
[cargo-binstall]: https://github.com/cargo-bins/cargo-binstall
