點燈坊

うまく使いさえすれば、時間はいつも十分にある

Integrating Alpine with Hugo

Sam Xiao's Avatar 2022-02-09

Alpine is great for JAMstack, but we have to integrate Alpine with Hugo manually.

Version

Hugo 0.92
Alpine 3.8

Create New Site

$ hugo new site hugo-alpine --format json
  • hugo new site : create a new site with default skeloton
  • --format json : use JSON as Hugo config format

alpine000

Add Packages

$ npm install -D alpinejs prettier npm-run-all
  • alpine : for Alpine
  • prettier : code formatter for HTML/CSS/JavaScript
  • npm-run-all : run NPM scripts in sequential or in parallel

alpine001

Prettier

alpine008

WebStorm -> Preferences -> Language & Frameworks -> Prettier

  • Prettier package : WebStorm will get a path automatically after installing Prettier
  • Rule for files : add html for Prettier to work with TailwindCSS
  • On Reformat Code action : run Prettier with the default Reformat code action
  • On save : run Prettier on save

After checking On Reformat Code action and On save, Prettier works as the default code formatter instead of WebStorm internal formatter

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>
    <title>Hello Hugo</title>
  </head>
  <body>
    <div>Hello Alpine</div>
    <div x-data="{ count: 0 }">
      <button @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 11

<div x-data="{ count: 0 }">
  <button @click="count++">+</button>
  <span x-text="count"/>
</div>

Classical counter implemented by Alpine.

alpine002

NPM Config

package.json

{
  "scripts": {
    "dev:alpine": "cp node_modules/alpinejs/dist/cdn.js static/alpine.js",
    "dev:hugo": "hugo server",
    "dev": "run-p dev:*",
    "build:alpine": "cp node_modules/alpinejs/dist/cdn.min.js static/alpine.js",
    "build:hugo": "hugo",
    "build": "run-s build:*"
  },
  "devDependencies": {
    "alpinejs": "^3.8.1",
    "npm-run-all": "^4.1.5",
    "prettier": "^2.5.1"
  }
}

Line 6

"dev:alpine": "cp node_modules/alpinejs/dist/cdn.js static/alpine.js",

Copy Alpine from node_modules to static folder.

Line 4

"dev:hugo": "hugo server",

Run web server by Hugo.

Line 5

"dev": "run-p dev:*",

run-p : run all dev:* in parallel under development mode.

Line 6

"build:alpine": "cp node_modules/alpinejs/dist/cdn.min.js static/alpine.js",

Copy minimized Alpine from node_modules to static folder.

Line 7

"build:hugo": "hugo",

Build markdown to the public folder by Hugo.

Line 8

"build": "run-s build:*"

run-s : run all build:* in sequential under production mode.

alpine003

Development Mode

$ npm run dev

Start web server under development mode.

alpine004

Alpine with Hugo is enabled successfully under development mode.

alpine005

Production Mode

$ npm run build
$ serve public
  • Build Hugo under production mode
  • Use serve to run web server

alpine006

Alpine with Hugo is enabled successfully under production mode.

alpine007

Conclusion

  • By integrating Alpine with Hugo, we can use JavaScript on HTML in declarative style