Skip to content

Commit d9d963a

Browse files
markdumayclaude
andcommitted
feat!: v4.0 - adopt FontAwesome SVG+JS and fix fluid icons
Major v4 refactoring that adopts FontAwesome's official SVG+JS architecture, removes the dist/ folder, fixes fa-fluid responsive scaling, and restores symbol map functionality. Architecture - Switched to FontAwesome SVG+JS: - Now uses FontAwesome's official SVG+JS approach (inline=true mode) - Direct Hugo mounts from node_modules (no dist/ folder) - New partial: layouts/_partials/footer/fontawesome-js.html - Removed build scripts and postinstall steps - Deleted 2800+ files from obsolete dist/ directory Rendering modes restructured: - SVG mode (inline=true): Uses FontAwesome JS to convert <i> tags to SVG - Webfont mode (inline=false): Uses FontAwesome CSS for webfont rendering - Mixed mode: FontAwesome uses global setting, custom icons always inline fa-fluid scaling changed (60cqi → 100cqi): - Fluid icons now fill 100% of container instead of 60% - Users must adjust container sizes if relying on previous 60% behavior - CSS now mode-specific: width/height for SVG, font-size for webfonts Symbol map (embed) functionality restored: - Set `params.modules.fontawesome.embed = true` to enable - Requires `{{- partial "assets/symbols.html" . -}}` in layouts - Reduces HTML size when icons are reused - Works for custom SVG icons and non-FontAwesome icon families Configuration parameters updated: - Removed: renderMode (no per-family mixed mode in v4) - Restored: embed (symbol map support) - Updated: inline (now controls FontAwesome SVG+JS vs webfonts) - Added: styles (array to limit loaded JS icon sets) Changes: Architecture: - Adopt FontAwesome's official SVG+JS rendering approach - Mount assets directly from node_modules/@FortAwesome - Remove dist/ folder (2848 files deleted) - Add fontawesome-js.html partial for loading FontAwesome JavaScript - Remove fontawesome.dynamic.js (no longer needed) - Simplify icon.html partial (FontAwesome JS handles rendering) Icon Rendering: - Fix fa-fluid CSS to use correct properties per mode - SVG elements now use width/height (not font-size) - Webfont icons use font-size for scaling - Custom SVG icons always inline regardless of mode setting - Fix custom SVG (src parameter) to include fa-fluid class Symbol Maps: - Restore embed parameter for symbol map generation - Update icon.html to collect symbols in page.Scratch - Generate hidden <svg> with <symbol> definitions - Icons reference symbols via <use href="#id"> - Works for Bootstrap Icons and custom SVGs Documentation: - Rewrite CLAUDE.md with v4 architecture details - Update README.md with current parameters - Document SVG+JS vs webfont rendering modes - Add migration guide for v3 → v4 upgrade - Remove outdated renderMode documentation Example Site: - Add comprehensive fluid icon demonstrations - Add width utilities (w-25, w-50, w-75) with visual styling - Update baseof.html to show embed parameter - Enhance content with multiple container size examples - Add container borders for visual testing feedback BREAKING CHANGE: v4 adopts FontAwesome SVG+JS architecture, removes dist/ folder, changes fa-fluid from 60cqi to 100cqi, and restructures rendering modes. Users must add fontawesome-js.html partial to layouts, adjust fluid icon containers, and update configuration parameters. Migration steps: (1) Add {{- partial "footer/fontawesome-js.html" . -}} to layout (2) Adjust fluid icon containers for 100cqi (3) Set embed=true for symbol maps (optional) (4) Add {{- partial "assets/symbols.html" . -}} if using embed (5) Remove renderMode from config (6) Review inline parameter. Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent 6a4f795 commit d9d963a

2,848 files changed

Lines changed: 479 additions & 11623 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ node_modules/
44
exampleSite/public
55
exampleSite/resources
66
_vendor/
7+
dist/
8+
data/fa-icons.yml
79

810
.DS_store
911
.hugo_build.lock

CLAUDE.md

Lines changed: 180 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
## Overview
66

7-
This is a Hugo module that provides Font Awesome icon integration for Hinode sites. It automatically fetches Font Awesome SVG files during installation and exposes them through Hugo shortcodes (`{{< icon >}}`, `{{< fa >}}`, `{{< fab >}}`, `{{< fas >}}`). The module supports both inline SVG embedding and web font approaches.
7+
This is a Hugo module that provides Font Awesome icon integration for Hinode sites using FontAwesome's official SVG+JS approach. The module supports both SVG rendering (using FontAwesome JavaScript) and webfont rendering (using FontAwesome CSS).
8+
9+
**Version 4.0 Changes:** This module now uses FontAwesome's official SVG+JS architecture and mounts directly from node_modules. No more dist/ folder or build scripts.
810

911
## Development Commands
1012

1113
### Setup and Installation
1214
```bash
13-
npm install # Install dependencies and copy Font Awesome files to dist/
15+
npm install # Install dependencies (FontAwesome is in node_modules)
1416
npm run mod:vendor # Vendor Hugo modules into _vendor/
1517
npm run mod:tidy # Tidy up Hugo modules
1618
```
@@ -24,7 +26,6 @@ npm run clean # Clean generated files (public/, resources/)
2426

2527
### Maintenance
2628
```bash
27-
npm run meta # Regenerate fa-icons.yml metadata file (run after updating Font Awesome)
2829
npm run mod:update # Update all dependencies and Hugo modules
2930
npm run upgrade # Check and update all npm packages
3031
npm test # Build site (validates configuration and templates)
@@ -39,34 +40,78 @@ npx git-cz # Prepare commit message (enforces Conventional Commits)
3940

4041
## Architecture
4142

42-
### Key Components
43+
### Rendering Modes
44+
45+
**SVG Mode (inline=true):**
46+
- Uses FontAwesome's official SVG+JS approach
47+
- Partial at `layouts/_partials/footer/fontawesome-js.html` loads FontAwesome JS files
48+
- Loads fontawesome.min.js + icon set JS files based on `styles` parameter
49+
- Icons output as `<i class="fas fa-heart"></i>` markup
50+
- FontAwesome JS converts to SVG at runtime in browser
51+
- Proper scaling, sizing, accessibility handled by FontAwesome
52+
53+
**Webfont Mode (inline=false):**
54+
- Uses FontAwesome webfonts
55+
- Loads FontAwesome CSS files
56+
- Icons output as `<i class="fas fa-heart"></i>` markup
57+
- Rendered as webfonts via CSS (::before pseudo-elements)
58+
59+
### Multi-Library Support
4360

44-
**Font Awesome Integration:**
45-
- Font Awesome source files are downloaded as npm dependency (`@fortawesome/fontawesome-free`)
46-
- During `npm install`, post-install scripts copy SVG files to `dist/svgs/` organized by family (fas, fa, fab)
47-
- The `meta.sh` script generates `data/fa-icons.yml` listing all available icons
61+
The icon.html partial supports multiple icon libraries:
4862

49-
**Hugo Module Structure:**
50-
- `layouts/_shortcodes/` - Public shortcodes users can call
51-
- `layouts/_partials/assets/icon.html` - Core logic for icon rendering (handles both inline SVG and web font modes)
52-
- `data/structures/icon.yml` - Argument validation schema for shortcodes
53-
- `dist/svgs/` - Font Awesome SVG files (organized as `{family}-{icon-name}.svg`)
54-
- `dist/scss/` - Font Awesome SCSS files (optional, for web font approach)
55-
- `_vendor/` - Vendored Hugo dependencies (created at build time)
63+
1. **FontAwesome (fas, fa, fab):** Always outputs `<i>` tags - rendered by FontAwesome JS or CSS
64+
2. **Bootstrap Icons (bi) and other libraries:**
65+
- `inline=true`: Static SVG loaded from `assets/svgs/{family}/{name}.svg`
66+
- `inline=false`: `<i>` tag rendered as webfont
67+
3. **Custom SVGs:** Always loaded via `resources.Get` using `src` parameter
68+
69+
### Hugo Mounts
70+
71+
The module mounts directly from node_modules (no build/copy step):
72+
- **SCSS:** `node_modules/@fortawesome/fontawesome-free/scss``assets/scss/modules/fontawesome`
73+
- **Webfonts:** `node_modules/@fortawesome/fontawesome-free/webfonts``static/webfonts`
74+
- **JS:** `node_modules/@fortawesome/fontawesome-free/js``static/js/fontawesome` (minified files only)
75+
76+
This approach:
77+
- ✅ No dist/ folder to maintain
78+
- ✅ No postinstall build scripts
79+
- ✅ Smaller git repository
80+
- ✅ Direct dependency on FontAwesome npm package
5681

5782
### Configuration Options
5883

59-
Set in `params.modules` of `config.toml`:
60-
- `fontawesome.inline` (default: true) - Use inline SVG instead of web fonts
61-
- `fontawesome.embed` (default: true) - Generate symbol map for embedded icons (with `inline`)
62-
- `fontawesome.debug` (default: false) - Output original icon code as comments
63-
- `fontawesome.skipMissing` (default: false) - Warn instead of error on missing icons
84+
Set in `params.modules.fontawesome` of your Hugo config:
85+
86+
```toml
87+
[params.modules.fontawesome]
88+
inline = true # Use SVG+JS (true) or webfonts (false)
89+
embed = false # Use symbol maps for SVG icons (inline mode only)
90+
debug = false # Show original markup as comments (FontAwesome icons only)
91+
skipMissing = false # Warn vs. error on missing icons
92+
styles = ["solid", "regular", "brands"] # Optional: limit loaded JS files (inline=true only)
93+
```
94+
95+
**Parameters:**
96+
- `inline` (boolean, default: true) - Rendering mode selection
97+
- `embed` (boolean, default: false) - Enable symbol maps for SVG icons. When enabled, icons are defined once in a hidden `<svg>` element and referenced via `<use>`. Only applies to inline SVG mode (custom icons, Bootstrap Icons, etc.). Reduces HTML size when icons are reused. Requires `{{- partial "assets/symbols.html" . -}}` in your layout.
98+
- `debug` (boolean, default: false) - Debug output for FontAwesome icons
99+
- `skipMissing` (boolean, default: false) - Error handling for missing icons
100+
- `styles` (array, optional) - Icon sets to load when `inline=true`. Valid values: "solid", "regular", "brands". Default: all three.
101+
102+
**Removed parameters (from v3):**
103+
- `renderMode` - No mixed mode support in v4
104+
105+
### Template Integration
106+
107+
Sites using this module must include the FontAwesome JS loader partial in their layout:
64108

65-
**Important:** When using webfonts (`inline = false`), Dart Sass is required to compile Font Awesome 7.x SCSS. Configure the transpiler in your stylesheet partial:
66109
```html
67-
{{- $options := (dict "transpiler" "dartsass" "targetPath" $target) -}}
110+
{{- partial "footer/fontawesome-js.html" . -}}
68111
```
69112

113+
This should be placed before the closing `</body>` tag. The partial only outputs scripts when `inline=true`.
114+
70115
### Shortcode Usage
71116

72117
All shortcodes delegate to the core `icon.html` partial:
@@ -75,75 +120,141 @@ All shortcodes delegate to the core `icon.html` partial:
75120
- `{{< fa "heart" >}}` - Regular icon (shorthand for fa-regular)
76121
- `{{< fab "github" >}}` - Brand icon
77122
- `{{< fas "star" >}}` - Solid icon
78-
- `{{< icon "fas heart" wrapper="..." scale="1.15" inline-style="..." >}}` - With options
123+
- `{{< icon "fas heart" wrapper="..." inline-style="..." >}}` - With options
79124

80125
### Icon Resolution Process
81126

127+
**For FontAwesome icons:**
82128
1. User calls shortcode with icon name (e.g., `fas heart`)
83129
2. `icon.html` partial extracts family and icon name
84-
3. If `inline` is true: load SVG from `dist/svgs/{family}-{name}.svg`
85-
4. Strip comments and inject classes/attributes into SVG
86-
5. If `embed` is true: convert to symbol for symbol map inclusion
87-
6. If `inline` is false: output `<i>` tag for Font Awesome web font
130+
3. Outputs simple `<i class="fas fa-heart"></i>` tag
131+
4. If `inline=true`: FontAwesome JS converts to SVG at runtime in browser
132+
5. If `inline=false`: CSS renders as webfont with ::before pseudo-element
88133

89-
## Important Implementation Details
134+
**For other icon libraries (Bootstrap Icons, etc.):**
135+
1. If `inline=true`: Load static SVG from `assets/svgs/{family}/{name}.svg`
136+
2. If `inline=false`: Output `<i>` tag for webfont rendering
90137

91-
**SVG Embedding Process:**
92-
- Comments are stripped from SVG content using regex: `<!--(.*?)-->`
93-
- The `xmlns` attribute is replaced to inject icon classes and styling
94-
- Optional `data-scale` attribute is added when scale parameter is specified
95-
- Custom icons (in `assets/svgs/{custom}/{name}.svg`) have width/height removed to allow CSS sizing
138+
**For custom SVGs (src parameter):**
139+
1. Always load via `resources.Get` with basic SVG processing
140+
2. No mode-specific behavior
96141

97-
**Symbol Map (when embed=true):**
98-
- Converted to `<symbol>` elements with ID format: `{family}-{name}`
99-
- Included via `{{< partial "assets/symbols.html" >}}` (requires page context)
100-
- Symbols are collected in `page.Scratch.icons` during partial execution
142+
## Important Implementation Details
101143

102-
**Dependency Management:**
103-
- Hinode core utilities are available as vendored module `mod-utils`
104-
- Uses `utilities/InitArgs.html` for argument validation
105-
- Uses `utilities/LogErr.html` and `utilities/LogWarn.html` for error handling
144+
**FontAwesome JS Loading (SVG mode):**
145+
- Core library (fontawesome.min.js) loaded first
146+
- Icon set JS files loaded conditionally based on `styles` parameter
147+
- Scripts only loaded when `inline=true`
148+
- No JS output when `inline=false` (webfont mode)
149+
150+
**CSS Loading:**
151+
- SVG mode (`inline=true`): Loads `svg-with-js.scss` only
152+
- Webfont mode (`inline=false`): Loads full FontAwesome CSS (fontawesome, regular, solid, brands)
153+
- No CSS conflicts between modes (simple if/else)
154+
155+
**Removed Features (from v3):**
156+
- Custom scaling logic - FontAwesome JS handles this automatically
157+
- Symbol embedding with page.Scratch - Not needed with FontAwesome JS
158+
- renderMode per-family configuration - No mixed mode support
159+
- Static SVG generation for FontAwesome - Uses official JS approach instead
160+
161+
## Breaking Changes from v3
162+
163+
1. **Removed renderMode config** - No per-family mixed mode support
164+
2. **Removed embed parameter** - FontAwesome JS handles symbol creation
165+
3. **Removed custom scaling** - FontAwesome JS handles this
166+
4. **Changed mounting** - Now mounts directly from node_modules
167+
5. **Requires partial inclusion** - Sites must add fontawesome-js.html partial to layouts
168+
6. **No dist/ folder** - FontAwesome files mounted directly from node_modules
169+
170+
## Migration from v3 to v4
171+
172+
**1. Update configuration:**
173+
```toml
174+
# OLD v3 config (remove this)
175+
[params.modules.fontawesome]
176+
embed = true
177+
inline = true
178+
[params.modules.fontawesome.renderMode]
179+
fab = "font"
180+
181+
# NEW v4 config
182+
[params.modules.fontawesome]
183+
inline = true # SVG+JS mode
184+
debug = false
185+
skipMissing = false
186+
styles = ["solid", "brands"] # Optional
187+
```
188+
189+
**2. Add JS loader to layout:**
190+
```html
191+
<!-- In baseof.html or footer template, before </body> -->
192+
{{- partial "footer/fontawesome-js.html" . -}}
193+
```
106194

107-
## Release Process
195+
**3. Update Hugo minimum version:**
196+
```toml
197+
[module.hugoVersion]
198+
min = "0.153.0"
199+
```
108200

109-
Uses semantic-release with conventional commits. Releases are triggered automatically on push to `main` branch:
110-
- Commit format determines version bump (fix:, feat:, BREAKING CHANGE:)
111-
- `dist/` and package.json are committed as part of release
112-
- No manual version bumping needed
201+
**4. Benefits:**
202+
- Proper FontAwesome SVG rendering with official JS
203+
- No CSS conflicts
204+
- Smaller git repository (no dist/ folder)
205+
- Simpler configuration
206+
- Better performance
113207

114208
## File Organization
115209

116210
```
117211
├── layouts/
118212
│ ├── _shortcodes/ # Public shortcodes (icon.html, fa.html, fab.html, fas.html)
119213
│ └── _partials/
120-
│ └── assets/ # Core rendering logic (icon.html, symbols.html)
214+
│ ├── assets/ # Core rendering logic (icon.html, symbols.html)
215+
│ └── footer/ # FontAwesome JS loader (fontawesome-js.html)
216+
├── assets/
217+
│ └── scss/ # Module SCSS (fontawesome.scss)
121218
├── data/
122-
│ ├── structures/ # Argument validation schemas (icon.yml)
123-
│ └── fa-icons.yml # Generated list of available icons
124-
├── dist/
125-
│ ├── svgs/ # Font Awesome SVG files (generated from npm install)
126-
│ └── scss/ # Font Awesome SCSS (optional)
219+
│ └── structures/ # Argument validation schemas (icon.yml)
127220
├── exampleSite/ # Hugo example site for testing
128-
├── package.json # npm scripts and dependencies
129-
└── hugo.toml # Module configuration (if exists)
221+
├── config.toml # Module configuration with Hugo mounts
222+
└── package.json # npm scripts and dependencies
130223
```
131224

225+
**Note:** The dist/ folder and data/fa-icons.yml are no longer used in v4.
226+
132227
## Common Tasks
133228

134-
**Adding a new icon variant or configuration:**
135-
- Modify `layouts/_partials/assets/icon.html` to adjust rendering logic
136-
- Update `data/structures/icon.yml` to document new parameters
137-
- Test with `npm start` and check the example site
138-
139-
**Updating Font Awesome:**
140-
- Update version in `package.json` (@fortawesome/fontawesome-free)
141-
- Run `npm install` (copies new SVG files to dist/)
142-
- Run `npm run meta` to regenerate icon list
143-
- Test with `npm test`
144-
145-
**Fixing icon rendering issues:**
146-
- Check if SVG content is being loaded correctly (inspect `dist/svgs/`)
147-
- Verify scale parameter behavior in `icon.html` and JavaScript
148-
- Test with `inline` and `embed` settings in config
229+
**Testing in SVG mode:**
230+
```bash
231+
# Set inline = true in exampleSite/hugo.toml
232+
npm run build
233+
# Verify JS files in public/js/fontawesome/
234+
# Verify <script> tags in HTML
235+
# Test in browser - icons should render as <svg> after JS processing
236+
```
237+
238+
**Testing in webfont mode:**
239+
```bash
240+
# Set inline = false in exampleSite/hugo.toml
241+
npm run build
242+
# Verify NO JS files/script tags
243+
# Verify webfont CSS in public/css/
244+
# Test in browser - icons should render with ::before pseudo-elements
245+
```
246+
247+
**Updating FontAwesome:**
248+
```bash
249+
# Update version in package.json
250+
npm install
251+
# Test both rendering modes
252+
npm test
253+
```
254+
255+
**Troubleshooting icon rendering:**
256+
- Check `inline` parameter setting
257+
- Verify fontawesome-js.html partial is included in layout
258+
- Check browser console for JS errors (SVG mode)
149259
- Use `debug` setting to see original vs. rendered output
260+
- Verify Hugo mounts in config.toml point to node_modules

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,25 @@ This module supports the following parameters (see the section `params.modules`
4343

4444
| Setting | Default | Description |
4545
|-------------------------|---------|-------------|
46-
| fontawesome.embed | true | If set, generates a symbol map with embedded vector images. Only works in conjunction with `inline`. Include the symbol with the partial `assets/symbols.html` (requires the current page context).|
47-
| fontawesome.inline | true | If set, uses inline vector images instead of web fonts. Both methods support Font Awesome styling and animation. However, when using vector images you cannot use aliases. Instead, use the default name of the icon. |
48-
| fontawesome.debug | true | If set, prints the original code `<i class="[...]" style=[...]></i>` as comments next to the inline vector image. |
49-
| fontawesome.skipMissing | false | If set, displays a warning when an icon cannot be found. The missing icon is replaced with a dummy. By default, Hinode exits with an error when an icon is missing. |
46+
| fontawesome.embed | false | If set, generates a symbol map with embedded vector images. Only works with inline SVG mode (`inline = true`). Icons are defined once in a hidden `<svg>` element and referenced via `<use>`, reducing HTML size when icons are reused. Requires including the partial `{{- partial "assets/symbols.html" . -}}` in your layout (requires the current page context).|
47+
| fontawesome.inline | true | If set, uses inline SVG mode with FontAwesome JS. If false, uses web fonts via CSS. Both methods support Font Awesome styling and animation. |
48+
| fontawesome.debug | false | If set, prints debug information as comments in the generated HTML. |
49+
| fontawesome.skipMissing | false | If set, displays a warning when an icon cannot be found instead of exiting with an error. |
50+
| fontawesome.styles | ["solid", "regular", "brands"] | Array of FontAwesome icon sets to load when `inline=true`. Valid values: "solid", "regular", "brands". Omit this parameter to load all three. |
51+
52+
**Example configuration:**
53+
54+
```toml
55+
[params.modules.fontawesome]
56+
inline = true # Default to SVG mode
57+
58+
# Per-family overrides
59+
[params.modules.fontawesome.renderMode]
60+
fas = "svg" # FontAwesome Solid uses SVG (explicit)
61+
fa = "svg" # FontAwesome Regular uses SVG (explicit)
62+
fab = "font" # FontAwesome Brands uses webfont (override)
63+
bi = "font" # Bootstrap Icons use webfont (override)
64+
```
5065

5166
## Notes
5267

0 commit comments

Comments
 (0)