Examples

Asset Pipeline

Hwaro includes a built-in asset pipeline that bundles, minifies, and fingerprints CSS and JS files for production-ready output.

Features

Configuration

Add an [assets] section to config.toml:

[assets]
enabled = true
minify = true
fingerprint = true

[[assets.bundles]]
name = "main.css"
files = ["css/reset.css", "css/style.css"]

[[assets.bundles]]
name = "app.js"
files = ["js/util.js", "js/app.js"]
Option Type Default Description
enabled bool false Enable the asset pipeline
minify bool true Minify CSS/JS output
fingerprint bool true Add content hash to filenames
source_dir string "static" Directory containing source files
output_dir string "assets" Output subdirectory in the build output

Bundle definition

Each [[assets.bundles]] entry defines a single output file:

Field Type Description
name string Output filename (e.g., "main.css")
files array Source files relative to source_dir

Files are concatenated in the order listed.

Template Usage

Use the asset() function in templates to reference bundled assets:

<link rel="stylesheet" href="{{ asset(name='main.css') }}">
<script src="{{ asset(name='app.js') }}"></script>

When fingerprinting is enabled, this resolves to the hashed path:

<link rel="stylesheet" href="https://example.com/assets/main.a1b2c3d4.css">

When the asset is not found in the pipeline manifest (e.g., not configured as a bundle), the function falls back to returning the path as-is under base_url.

asset_url is available as an alias for asset.

How It Works

  1. During the Initialize phase, the pipeline reads source files from source_dir
  2. Files listed in each bundle are concatenated in order
  3. If minify is enabled, CSS/JS-specific minification is applied
  4. If fingerprint is enabled, an 8-character SHA-256 hash is inserted before the extension
  5. The output is written to {output_dir}/{output_name} in the build directory
  6. A manifest mapping original names to output paths is stored for template resolution

Minification

The built-in minifiers are conservative and safe:

CSS:

JS:

For more aggressive minification, use build hooks with external tools like esbuild or terser.

Examples

Basic CSS bundle

[assets]
enabled = true

[[assets.bundles]]
name = "style.css"
files = ["css/normalize.css", "css/base.css", "css/layout.css"]
<link rel="stylesheet" href="{{ asset(name='style.css') }}">

Multiple bundles

[assets]
enabled = true

[[assets.bundles]]
name = "vendor.css"
files = ["css/vendor/normalize.css", "css/vendor/highlight.css"]

[[assets.bundles]]
name = "site.css"
files = ["css/base.css", "css/components.css"]

[[assets.bundles]]
name = "app.js"
files = ["js/search.js", "js/nav.js"]

Development without fingerprinting

[assets]
enabled = true
minify = false
fingerprint = false

[[assets.bundles]]
name = "style.css"
files = ["css/style.css"]

See Also