Hugo is great for JAMstack, but we have to use vanilla JavaScript and CSS to create templates. With Alpine and TailwindCSS, we can create layouts by declarative style directly in HTML.
Version
Hugo 0.92
Alpine 3.8
TailwindCSS 3.0
Create New Site
$ hugo new site hugo-hat --format json
hugo new site
: create a new site with default skeloton--format json
: use JSON as Hugo config format
Add Packages
$ npm install -D tailwindcss alpinejs prettier prettier-plugin-tailwindcss npm-run-all
tailwindcss
: for TailwindCSSalpinejs
: for Alpineprettier
: code formatter for HTML/CSS/JavaScriptprettier-plugin-tailwindcss
: code formatter for TailwindCSSnpm-run-all
: run NPM scripts in sequential or in parallel
Prettier
WebStorm -> Preferences -> Language & Frameworks -> Prettier
Prettier package
: WebStorm will get a path automatically after installing PrettierRule for files
: addhtml
for Prettier to work with TailwindCSSOn Reformat Code action
: run Prettier with the defaultReformat code
actionOn save
: run Prettier on save
After checking
On Reformat Code action
andOn save
, Prettier works as the default code formatter instead of WebStorm internal formatter
TailwindCSS Config
$ npx tailwindcss init
Use Tailwind CLI to generate default tailwind.config.js
.
tailwind.config.js
module.exports = {
content: ["content/**/*.md", "layouts/**/*.html"],
theme: {
extend: {},
},
plugins: [],
};
Line 2
content: ["content/**/*.md", "layouts/**/*.html"],
Purge unused CSS by specified file extensions.
CSS
input.css
@tailwind base;
@tailwind components;
@tailwind utilities;
- Add
index.css
on the root folder of project - Tailwind CLI transpiles
input.css
tooutput.css
Hugo Config
config.json
{
"baseURL": "http://example.org/",
"languageCode": "en-us",
"title": "My New Hugo Site",
"minify": {
"tdewolff": {
"html": {
"keepWhitespace": false
}
}
}
}
keepWhitespace
: Hugo keeps white space by default. We have to set it to false
to minimize white space on HTML
Layout
layouts/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="alpine.js" defer></script>
<link rel="stylesheet" href="output.css" />
<title>HATstack</title>
</head>
<body>
<div class="text-4xl text-red-700">Hello HATstack</div>
<div x-data="{ count: 0 }">
<button
class="rounded-lg bg-gray-200 px-3 py-1 text-gray-800"
@click="count++"
>
+
</button>
<span x-text="count" />
</div>
</body>
</html>
Line 6
<script src="alpine.js" defer></script>
Only reference the local path of Alpine so that we can run Hugo locally without an internet connection.
Line 7
<link rel="stylesheet" href="output.css" />
Link CSS file to output.css
which is transpiled by Tailwind CLI.
Line 11
<div class="text-4xl text-red-700">Hello HATstack</div>
Use TailwindCSS utilities for HTML.
Line 12
<div x-data="{ count: 0 }">
<button
class="rounded-lg bg-gray-200 px-3 py-1 text-gray-800"
@click="count++"
>
+
</button>
<span x-text="count" />
</div>
Classical counter implemented by Alpine.
NPM Config
package.json
{
"scripts": {
"dev:css": "npx tailwindcss -i input.css -o static/output.css -w",
"dev:alpine": "cp node_modules/alpinejs/dist/cdn.js static/alpine.js",
"dev:hugo": "hugo server",
"dev": "run-p dev:*",
"build:css": "NODE_ENV=production npx tailwindcss -i input.css -o static/output.css -m",
"build:alpine": "cp node_modules/alpinejs/dist/cdn.min.js static/alpine.js",
"build:hugo": "hugo --cleanDestinationDir --minify",
"build": "run-s build:*"
},
"devDependencies": {
"alpinejs": "^3.8.1",
"npm-run-all": "^4.1.5",
"prettier": "^2.5.1",
"prettier-plugin-tailwindcss": "^0.1.7",
"tailwindcss": "^3.0.19"
}
}
Line 3
"dev:css": "npx tailwindcss -i input.css -o static/output.css -w",
Use Tailwind CLI to build CSS under development mode :
-i input.css
: useinput.css
as the source CSS file-o static/output.css
: useoutput.css
as the target CSS file-w
: watch for changes and rebuild as needed
Line 4
"dev:alpine": "cp node_modules/alpinejs/dist/cdn.js static/alpine.js",
Copy Alpine from node_modules
to static
folder.
Line 5
"dev:hugo": "hugo server",
Run web server by Hugo.
Line 6
"dev": "run-p dev:*",
run-p
: run all dev:*
in parallel under development mode.
Line 7
"build:css": "NODE_ENV=production npx tailwindcss -i input.css -o static/output.css -m",
Use Tailwind CLI to build CSS under production mode :
-i input.css
: useinput.css
as source CSS file-o static/output.css
: useoutput.css
as target CSS file-m
: minify target CSS file
Line 8
"build:alpine": "cp node_modules/alpinejs/dist/cdn.min.js static/alpine.js",
Copy minimized Alpine from node_modules
to static
folder.
Line 9
"build:hugo": "hugo --cleanDestinationDir --minify",
Build HTML/CSS/JavaScript for production.
cleanDestinationDir
: clean up thepublic
folder before building the siteminify
: remove whitespace characters, resulting in smaller file sizes that will make the site download faster for our visitors
Line 10
"build": "run-s build:*"
run-s
: run all build:*
in sequential under production mode.
Development Mode
$ npm run dev
Start web server under development mode.
TailwindCSS and Alpine with Hugo are enabled successfully under development mode.
HTML is not minimized under development mode.
Production Mode
$ npm run build
$ serve public
Build HTML/CSS/JavaScript with minifier under production mode.
TailwindCSS and Alpine with Hugo are enabled successfully under production mode.
HTML is minimized under production mode.
Conclusion
- It’s not too difficult to integrate HATstack with Hugo. With Alpine and TailwindCSS, we can start to create templates by declarative style directly in HTML
- Minimizing HTML is provided by Hugo. We don’t have to use other packages