Nixentric
Hugo

Cara Terbaik Instalasi Tailwind CSS di Hugo

Tailwind CSS menjadi salah satu framework CSS yang paling digemari pengguna SSG Hugo. Hal itu terbuktikan dengan banyaknya metode instalasi framework ini yang bertebaran di Internet.

Namun, kebanyakan dari metode-metode itu tidak sesuai standar dokumentasi gohugo.io. Sehingga, saya berfikir untuk membuat sebuah metode yang terbaik menurut saya yang berdasarkan dokumentasi.

Adapun caranya sebagai berikut:

Instalasi Packages

Disini saya asumsikan kamu sudah bisa menginstal proyek Hugo mu sendiri & sudah menginstal Node.js.

Pastikan juga kamu sudah menginstal package.json ke dalam proyekmu, jika belum gunakan command berikut:

npm init -y

Lalu, jalankan command berikut untuk instal dependencies yang dibutuhkan:

npm install -D tailwindcss postcss postcss-cli autoprefixer cssnano

Disini kita menggunakan Postcss sebagai preprocessor untuk mengoptimalisasi CSS pada TailwindCSS. Alasan penggunaan PostCSS dikarenakan tools ini telah di-support langsung oleh Hugo, sehingga meminimalkan kendala yang akan menyusahkan di masa depan.

Disini kita juga menggunakan autoprefixer untuk memastikan kompatibilitas CSS di berbagai browser yang berbeda.

Sedangkan, cssnano digunakan untuk mengopmalisasi dengan me-minimize (meringkas) kode CSS secara efektif agar file CSS tidak berat saat deploy ke production environment.

Konfigurasi

Pertama-tama, konfigurasi hugo.toml yang berada di path root dengan kode berikut:

[build]
  writeStats = true

Penjelasan:

Ketika diaktifkan, fitur ini akan membuat file hugo_stats.json. File ini akan menampilkan seluruh atribut class dan id HTML yang ada di proyek Hugo kita. Tentu, ini sangat penting bagi Tailwind untuk mendeteksi seluruh class yang ada di proyek Hugo.


Selanjutnya, buatlah file config postcss.config.js & tailwind.config.js di path root proyek Hugo.

postcss.config.js berisi:

// When deploying to production, set the base directory to your Hugo project's root directory.
// Ini berguna Ketika melakukan deploy ke production, ia akan mengarahkan ke root proyek Hugo-mu.
const baseDir = __dirname;

let tailwindConfig =
  process.env.HUGO_FILE_TAILWIND_CONFIG_JS || baseDir + "./tailwind.config.js";
const tailwind = require("tailwindcss")(tailwindConfig);
const autoprefixer = require("autoprefixer")({ path: [baseDir] });
const cssnanoPlugin = require("cssnano")({
  path: [baseDir],
  preset: [
    "default",
    {
      discardComments: {
        removeAll: true,
      },
    },
  ],
});

module.exports = {
  plugins: [
    tailwind,
    autoprefixer,
    ...(process.env.HUGO_ENVIRONMENT === "production" ? [cssnanoPlugin] : []),
  ],
};

tailwind.config.js berisi:

// When deploying to production, set the base directory to your Hugo project's root directory.
// Ini berguna Ketika melakukan deploy ke production, ia akan mengarahkan base directory ke root proyek Hugo-mu.
const baseDir = __dirname;

/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: "class",
  content: [
    `${baseDir}/themes/**/layouts/**/*.html`,
    `${baseDir}/content/**/layouts/**/*.html`,
    `${baseDir}/layouts/**/*.html`,
    `${baseDir}/content/**/*.html`,
    `${baseDir}/content/**/*.md`,
    `${baseDir}/data/**/*.yaml`,
    `${baseDir}/public/**/*.html`,
    `${baseDir}/hugo_stats.json`,
  ],
  theme: {
    extend: {},
  },
  plugins: [],
  variants: [],
};

Kemudian, tentukan lokasi assets .css Tailwind-mu. Biasanya, saya letakan di /assets/css/tailwind.css.

archetypes/
assets/
└── css/
│   └── tailwind.css
└── js/

di dalam file tailwind.css masukan kode berikut:

@tailwind base;
@tailwind components;
@tailwind utilities;

Tahap selanjutnya adalah, membuat partial template yang digunakan untuk memproses tailwind CSS menjadi CSS utuh, agar dapat ditampilkan ke dalam proyek Hugo.

Contoh, saya disini membuat partial dengan nama file styles.html di dalam folder layouts/partials/head:

layouts/
└── partials/
    ├── head/
    │   ├── favicons.html
    │   ├── metadata.html
    │   └── styles.html (File Partials yang saya buat)

Di dalam file tersebut, masukan kode berikut:

{{/* styles */}}
{{- $options := dict "inlineImports" true -}}
{{- $tailwind := resources.Get "css/styles.css" -}}
{{- $slices := slice $tailwind | resources.Concat "css/app.css" -}}
{{- $styles := $slices |  resources.PostCSS $options -}}

{{/* Output */}}
{{- if eq hugo.Environment "development" -}}

<link rel="stylesheet" href="{{ $styles.Permalink | absURL }}" />
{{- else -}}
{{/* Production Environtment */}}
{{- $styles := $styles | minify | fingerprint | resources.PostProcess -}}
<link rel="stylesheet" href="{{ $styles.Permalink }}" integrity="{{ $styles.Data.Integrity }}"/>
{{- end -}}

Penjelasan:

  • Seperti yang saya singgung sebelumnya, Hugo sudah sangat mendukung penggunaan PostCSS. Maka, banyak fitur yang secara native sudah tersedia di Hugo, seperti inlineImports berguna untuk menggunakan fitur @import kedalam CSS-mu. dan menurut saya, fitur ini juga akan sangat berguna saat pengembangan proyek Hugo.
  • Kemudian, ada resources.Get berfungsi untuk mengambil lokasi path file yang ada di folder assets.
  • Sedangkan, resources.Concat ini berguna untuk mem-bundle beberapa file resources ke dalam 1 file. Selain itu saya juga menggunakan ini agar nama file source dan output jadi berbeda.
  • Saya juga membedakan output saat development dengan Production output. Hal ini karena saat development saya ingin code CSS lebih mudah dibaca sedangkan saat production saya ingin file-nya lebih ringkas dan ringan.

Setelah membuat file tersebut, letakan partialnya ke dalam tag <head> yang biasanya berada di path layouts/_default/baseof.html atau biar lebih rapih lagi letakan di layouts/_default/partials/head.html.

<head>
...
{{- partial "head/css.html" . -}}
...
</head>

Di Hugo, ada satu permasalahan Tailwind yang sering ditemui, yaitu tidak responsifnya penambahan CSS untuk class Tailwind yang ingin kita gunakan, sehingga, style class yang kita gunakan tidak berfungsi dengan semestinya. Hal itu disebabkan oleh Hugo yang me-cache hasil render pada output CSS dan tidak melakukan re-cache meski ada perubahan yang dilakukan. Untuk mengatasi itu, kita bisa menggunakan fitur chachebusters.

Fungsi chacehbusters ini berguna untuk rebuild file .css saat ada perubahan.

Cara menggunakannya, pergi ke file konfigurasi hugo.toml, dan masukan kode berikut:

[module]
  [[module.mounts]]
    source = 'content'
    target = 'content'
  [[module.mounts]]
    source = 'static'
    target = 'static'
  [[module.mounts]]
    source = 'layouts'
    target = 'layouts'
  [[module.mounts]]
    source = 'data'
    target = 'data'
  [[module.mounts]]
    source = 'assets'
    target = 'assets'
  [[module.mounts]]
    source = 'i18n'
    target = 'i18n'
  [[module.mounts]]
    source = 'archetypes'
    target = 'archetypes'
  [[module.mounts]]
    source = "hugo_stats.json"
    target = "assets/watching/hugo_stats.json"

[build]
  writeStats = true
  [[build.cachebusters]]
    source = "assets/watching/hugo_stats\\.json"
    target = "app\\.css"
  [[build.cachebusters]]
    source = "(postcss|tailwind)\\.config\\.js"
    target = "css"
  [[build.cachebusters]]
    source = "assets/.*\\.(js|ts|jsx|tsx)"
    target = "js"
  [[build.cachebusters]]
    source = "assets/.*\\.(.*)$"
    target = "$1"

Catatan: Jika kamu sebelumnya sudah mererapkan writeStats = true, kamu replace saja dengan semua dengan kode di atas ini.


Untuk memastikan tidak ada kendala saat development style Tailwind CSS. Gunakan command webserver berikut:

hugo server --ignoreCache --noHTTPCache --disableFastRender --gc

Penjelasan:

  • --ignoreCache : Mengabaikan cache yang dibuat Hugo pada proses build sebelumnya.

  • --noHTTPCache : Menonaktifkan cache HTTP pada browser.

  • --disableFastRender : Menonaktifkan fitur fast render Hugo.

    Rincian: Saat masa development, fitur fast render lebih baik di matikan, untuk menggunakannya tambahkan --disableFastRender pada command.

    Tetapi, jika hanya membuat konten, fitur ini lebih baik tidak dipakai, karena sebenarnya fitur fast render berguna untuk mempercepat proses build.

  • --gc : Menjalankan garbage collection (GC) yang berguna untuk membersihkan cache Hugo dari file yang tidak terpakai.


Untuk production, jangan lupa untuk menambahkan config berikut di folder config/production:

assets/
layouts/
└── _default/
└── production
    └── hugo.html

Dan masukan kode konfigurasi berikut kedalam hugo.toml

[build.buildStats]
    enable = true

Kegunaannya untuk membersihkan CSS yang tidak digunakan saat di deploy ke production environment.

Untuk deploy ke production gunakan command berikut:

hugo --gc --minify

Semoga bermanfaat! ❤️