HTML Transforms and Minification
**Referenced Files in This Document** - [.eleventy.js](file://.eleventy.js) - [package.json](file://package.json) - [src/content/knowledge/getting-started.md](file://src/content/knowledge/getting-started.md) - [src/content/knowledge/knowledge.11tydata.js](file://src/content/knowledge/knowledge.11tydata.js) - [src/legal/code-of-conduct.njk](file://src/legal/code-of-conduct.njk) - [netlify.toml](file://netlify.toml) - [cloudflare-pages.toml](file://cloudflare-pages.toml)Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
Introduction
This document explains Eleventy’s HTML transform system as implemented in this project, focusing on two transforms:
- obsidianSyntax: converts Obsidian-style wiki links and callout blocks into HTML.
- htmlmin: minifies HTML output in production builds using html-minifier-terser.
It also covers the transform pipeline execution order, conditional behavior based on NODE_ENV, and how transforms integrate into the build process. Guidance is included for creating custom transforms, debugging transform issues, and understanding the performance impact of minification options.
Project Structure
Eleventy configuration and transforms are defined in the Eleventy configuration file. Content and layouts are organized under src/, and the build output is placed in _site/.
graph TB
A[".eleventy.js<br/>Defines transforms and build settings"] --> B["_site/<br/>Build output"]
C["src/content/knowledge/getting-started.md<br/>Obsidian-style wiki links and callouts"] --> D["Knowledge layout<br/>knowledge.11tydata.js"]
E["src/legal/code-of-conduct.njk<br/>Standard HTML content"] --> B
F["package.json<br/>Dependencies incl. html-minifier-terser"] --> G["Transform runtime"]
H["netlify.toml<br/>Build command and environment"] --> B
I["cloudflare-pages.toml<br/>Legacy Pages config"] --> B
Diagram sources
- [.eleventy.js:212-283](file://.eleventy.js#L212-L283)
- [package.json:14-21](file://package.json#L14-L21)
- [src/content/knowledge/getting-started.md:17-35](file://src/content/knowledge/getting-started.md#L17-L35)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
- [src/legal/code-of-conduct.njk:1-65](file://src/legal/code-of-conduct.njk#L1-L65)
- [netlify.toml:1-26](file://netlify.toml#L1-L26)
- [cloudflare-pages.toml:1-17](file://cloudflare-pages.toml#L1-L17)
Section sources
- [.eleventy.js:212-283](file://.eleventy.js#L212-L283)
- [package.json:14-21](file://package.json#L14-L21)
- [src/content/knowledge/getting-started.md:17-35](file://src/content/knowledge/getting-started.md#L17-L35)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
- [src/legal/code-of-conduct.njk:1-65](file://src/legal/code-of-conduct.njk#L1-L65)
- [netlify.toml:1-26](file://netlify.toml#L1-L26)
- [cloudflare-pages.toml:1-17](file://cloudflare-pages.toml#L1-L17)
Core Components
- obsidianSyntax transform
- Purpose: Converts Obsidian-style wiki links and callout blocks into HTML anchors and callout containers.
- Behavior: Runs on all HTML outputs (.html) and replaces wiki link patterns and callout block patterns with semantic HTML.
- Example usage: See Obsidian-style wiki links and callout blocks in knowledge content.
- htmlmin transform
- Purpose: Minifies HTML in production builds to reduce payload size.
- Behavior: Conditionally registered when NODE_ENV equals production. Uses html-minifier-terser with a curated set of options.
- Integration: Registered alongside other transforms in the Eleventy configuration.
Section sources
- [.eleventy.js:216-239](file://.eleventy.js#L216-L239)
- [.eleventy.js:241-261](file://.eleventy.js#L241-L261)
- [src/content/knowledge/getting-started.md:17-35](file://src/content/knowledge/getting-started.md#L17-L35)
Architecture Overview
The transform pipeline runs after templates render and before content is written to disk. The order of execution is determined by the order transforms are registered. In this project:
- obsidianSyntax runs first to convert wiki links and callouts.
- htmlmin runs second (only in production) to minify the resulting HTML.
sequenceDiagram
participant T as "Template Engine"
participant O as "obsidianSyntax Transform"
participant M as "htmlmin Transform"
participant FS as "File System"
T->>O : Rendered HTML content
O-->>M : Converted HTML (wiki links, callouts)
alt NODE_ENV === "production"
M-->>FS : Minified HTML
else Not production
M-->>FS : Unchanged HTML
end
Diagram sources
- [.eleventy.js:216-261](file://.eleventy.js#L216-L261)
Section sources
- [.eleventy.js:216-261](file://.eleventy.js#L216-L261)
Detailed Component Analysis
obsidianSyntax Transform
Purpose:
- Convert Obsidian-style wiki links into HTML anchors.
- Convert Obsidian-style callout blocks into semantic callout containers.
Behavior:
- Only applies to HTML outputs (.html).
- Wiki links: Matches patterns like Title or Text and converts them to anchors with a specific class and URL structure.
- Callouts: Matches blockquote paragraphs starting with [!type] and converts them into divs with roles and classes indicating the callout type.
flowchart TD
Start(["Transform Entry"]) --> CheckExt["Check outputPath ends with '.html'"]
CheckExt --> |No| ReturnOriginal["Return original content"]
CheckExt --> |Yes| ReplaceWiki["Replace wiki links with anchors"]
ReplaceWiki --> ReplaceCallouts["Replace callout blocks with callout divs"]
ReplaceCallouts --> ReturnModified["Return transformed content"]
Diagram sources
- [.eleventy.js:216-239](file://.eleventy.js#L216-L239)
Examples in content:
- Wiki links and callouts are demonstrated in the knowledge content file.
- The knowledge layout and computed permalink are configured to support the generated wiki link URLs.
Section sources
- [.eleventy.js:216-239](file://.eleventy.js#L216-L239)
- [src/content/knowledge/getting-started.md:17-35](file://src/content/knowledge/getting-started.md#L17-L35)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
htmlmin Transform
Purpose:
- Minify HTML in production builds to reduce payload size.
Behavior:
- Conditional registration: Only added when NODE_ENV equals production.
- Applies html-minifier-terser to HTML outputs (.html).
- Uses a set of options designed to preserve semantics while reducing size.
flowchart TD
Start(["Transform Entry"]) --> CheckEnv["Check NODE_ENV === 'production'"]
CheckEnv --> |No| ReturnOriginal["Return original content"]
CheckEnv --> |Yes| CheckExt["Check outputPath ends with '.html'"]
CheckExt --> |No| ReturnOriginal
CheckExt --> |Yes| Minify["Minify HTML with html-minifier-terser"]
Minify --> ReturnMinified["Return minified content"]
Diagram sources
- [.eleventy.js:241-261](file://.eleventy.js#L241-L261)
Integration with build process:
- The build command invokes Eleventy, which executes transforms during rendering.
- Deployment platforms (Netlify, Cloudflare) run the same build command.
Section sources
- [.eleventy.js:241-261](file://.eleventy.js#L241-L261)
- [netlify.toml:1-26](file://netlify.toml#L1-L26)
- [cloudflare-pages.toml:1-17](file://cloudflare-pages.toml#L1-L17)
Dependency Analysis
- html-minifier-terser is declared as a dependency and required conditionally in the transform.
- The transform depends on Node’s process.env for conditional behavior.
- Build commands and environment variables are configured in platform-specific TOML files.
graph LR
P["package.json<br/>Dependencies"] --> HMT["html-minifier-terser"]
ECFG[".eleventy.js<br/>Transform registration"] --> HMT
ENV["Environment<br/>NODE_ENV"] --> ECFG
NET["netlify.toml<br/>Build command"] --> ECFG
CF["cloudflare-pages.toml<br/>Build command"] --> ECFG
Diagram sources
- [package.json:14-21](file://package.json#L14-L21)
- [.eleventy.js:241-261](file://.eleventy.js#L241-L261)
- [netlify.toml:1-26](file://netlify.toml#L1-L26)
- [cloudflare-pages.toml:1-17](file://cloudflare-pages.toml#L1-L17)
Section sources
- [package.json:14-21](file://package.json#L14-L21)
- [.eleventy.js:241-261](file://.eleventy.js#L241-L261)
- [netlify.toml:1-26](file://netlify.toml#L1-L26)
- [cloudflare-pages.toml:1-17](file://cloudflare-pages.toml#L1-L17)
Performance Considerations
- Minification options:
- collapseBooleanAttributes, collapseWhitespace, removeComments, removeEmptyAttributes, removeRedundantAttributes, sortAttributes, sortClassName, useShortDoctype, decodeEntities, includeAutoGeneratedTags=false.
- These options reduce bytes while preserving semantics and accessibility attributes.
- Impact:
- Smaller HTML payloads improve network transfer and parsing performance.
- Minification adds CPU overhead during build; ensure builds run on adequate CI resources.
- Environment gating:
- htmlmin runs only in production, avoiding unnecessary CPU cost in development.
[No sources needed since this section provides general guidance]
Troubleshooting Guide
Common issues and resolutions:
- Wiki links not converting:
- Verify the content is rendered to HTML (outputPath ends with .html).
- Confirm the obsidianSyntax transform is registered and not overridden by another transform.
- Callout blocks not rendering:
- Ensure the blockquote paragraph starts with [!type] and the content follows the expected structure.
- Check that the transform runs before htmlmin if whitespace trimming affects formatting.
- Minification breaking functionality:
- Temporarily disable htmlmin by setting NODE_ENV to a non-production value during testing.
- Review minification options if attributes or comments are removed unexpectedly.
- Debugging transforms:
- Add logging inside the transform function to inspect content and outputPath.
- Use Eleventy’s development server to preview changes without minification.
- Conditional execution:
- Confirm NODE_ENV is set to production when building for deployment.
- Verify platform configuration (Netlify, Cloudflare) runs the build command.
Section sources
- [.eleventy.js:216-261](file://.eleventy.js#L216-L261)
- [netlify.toml:1-26](file://netlify.toml#L1-L26)
- [cloudflare-pages.toml:1-17](file://cloudflare-pages.toml#L1-L17)
Conclusion
The project’s transform system provides two key capabilities:
- obsidianSyntax converts Obsidian-style wiki links and callouts into semantic HTML.
- htmlmin reduces HTML payload size in production builds.
Transforms are registered in order, with htmlmin gated by NODE_ENV. The build integrates seamlessly with Netlify and Cloudflare deployments via their respective configuration files.
[No sources needed since this section summarizes without analyzing specific files]
Appendices
Creating a Custom Transform
Steps:
- Register a new transform with a unique name in the Eleventy configuration.
- Implement logic to modify content based on outputPath.
- Ensure the transform targets the correct output types (e.g., .html).
- Test locally with NODE_ENV set appropriately.
Example reference:
- See the existing obsidianSyntax and htmlmin registrations for structure and patterns.
Section sources
- [.eleventy.js:216-261](file://.eleventy.js#L216-L261)
Transform Pipeline Execution Order
- Registration order determines execution order.
- In this project:
- obsidianSyntax is registered first.
- htmlmin is registered second (only in production).
- The final HTML is written to disk after all transforms have processed it.
Section sources
- [.eleventy.js:216-261](file://.eleventy.js#L216-L261)
Conditional Execution Based on NODE_ENV
- htmlmin is conditionally added when NODE_ENV equals production.
- Development builds bypass minification to speed up iteration and simplify debugging.
Section sources
- [.eleventy.js:241-261](file://.eleventy.js#L241-L261)
Integration with the Build Process
- Build command:
- Netlify: runs npm run build.
- Cloudflare: legacy Pages config mirrors the same command.
- Output:
- Eleventy writes to _site/, which is the publish directory for both platforms.
Section sources
- [netlify.toml:1-26](file://netlify.toml#L1-L26)
- [cloudflare-pages.toml:1-17](file://cloudflare-pages.toml#L1-L17)