Salin dan Bagikan
Tutorial Konfigurasi Tailwind CSS di Hugo dengan PostCSS - Tutorial step-by-step konfigurasi Tailwind CSS dengan PostCSS di Hugo. Setup build pipeline, …

Tutorial Konfigurasi Tailwind CSS di Hugo dengan PostCSS

Tutorial Konfigurasi Tailwind CSS di Hugo dengan PostCSS

Integrasi Tailwind CSS dengan Hugo melalui PostCSS adalah kombinasi yang powerful untuk membangun website modern. Tutorial ini akan membimbing Anda dari setup awal hingga optimasi production-ready.

Apa itu Tailwind CSS dan PostCSS?

Tailwind CSS

Tailwind adalah utility-first CSS framework yang memungkinkan styling langsung di HTML tanpa menulis CSS custom. Keunggulan:

  • Utility classes: Ratusan class siap pakai (flex, pt-4, text-center, etc)
  • Highly customizable: Konfigurasi melalui JavaScript
  • JIT mode: Generate hanya class yang digunakan
  • Responsive design: Breakpoint built-in (sm, md, lg, xl)
  • Dark mode: Support otomatis

PostCSS

PostCSS adalah tool untuk transformasi CSS dengan JavaScript plugins:

  • Autoprefixer: Menambahkan vendor prefixes otomatis
  • CSS nesting: Support nested selectors
  • Custom properties: CSS variables dengan fallback
  • Future CSS: Polyfill fitur CSS modern
  • Minification: Compress CSS untuk production

Prerequisites

Yang Harus Diinstall

  1. Hugo Extended: Pastikan menggunakan versi extended untuk support PostCSS

    # Cek versi Hugo
    hugo version
    
    # Harus ada kata "extended" di output
    # Contoh: hugo v0.123.0+extended linux/amd64
    
  2. Node.js dan NPM: Untuk mengelola packages

    node --version  # v18 atau lebih tinggi
    npm --version
    
  3. Text Editor: VS Code dengan ekstensi:

    • Tailwind CSS IntelliSense
    • PostCSS Language Support
    • Hugo Language and Syntax Support

Step-by-Step Setup

Step 1: Inisialisasi Project Node.js

Di root project Hugo Anda:

# Inisialisasi package.json
npm init -y

# Install Tailwind CSS dan PostCSS
npm install -D tailwindcss postcss autoprefixer

# Generate config file Tailwind
npx tailwindcss init -p

Output yang akan dihasilkan:

  • package.json - File konfigurasi NPM
  • tailwind.config.js - Konfigurasi Tailwind
  • postcss.config.js - Konfigurasi PostCSS

Step 2: Konfigurasi Tailwind CSS

Edit file tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    // Path ke semua template Hugo
    './layouts/**/*.html',
    './content/**/*.md',
    './content/**/*.html',
    './assets/**/*.js',
    
    // Jika menggunakan themes
    './themes/**/layouts/**/*.html',
    
    // HUGO_ENVIRONMENT adalah production
    ...(process.env.HUGO_ENVIRONMENT === 'production' ? [] : ['./layouts/_default/*.html']),
  ],
  theme: {
    extend: {
      // Custom colors
      colors: {
        primary: {
          50: '#eff6ff',
          100: '#dbeafe',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
          900: '#1e3a8a',
        },
        secondary: '#64748b',
      },
      
      // Custom font families
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
        serif: ['Merriweather', 'serif'],
      },
      
      // Custom spacing
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },
      
      // Custom breakpoints
      screens: {
        'xs': '475px',
        '3xl': '1600px',
      },
    },
  },
  plugins: [
    // Tambahkan plugin jika diperlukan
    // require('@tailwindcss/typography'),
    // require('@tailwindcss/forms'),
  ],
  
  // Optimasi untuk production
  purge: {
    enabled: process.env.HUGO_ENVIRONMENT === 'production',
    content: [
      './layouts/**/*.html',
      './content/**/*.md',
    ],
  },
}

Penjelasan konfigurasi:

  • content: Path file yang akan di-scan Tailwind untuk menemukan class yang digunakan
  • theme.extend: Menambahkan custom values tanpa override defaults
  • purge: Menghapus unused CSS di production (sangat penting untuk ukuran file kecil)

Step 3: Setup PostCSS

Edit file postcss.config.js:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {
      overrideBrowserslist: [
        '> 1%',
        'last 2 versions',
        'not dead',
        'not ie 11',
      ],
    },
  },
}

Konfigurasi Autoprefixer:

  • > 1%: Support browser dengan usage > 1%
  • last 2 versions: 2 versi terakhir dari setiap browser
  • not dead: Exclude browser yang tidak lagi maintained

Step 4: Buat File CSS Entry Point

Buat folder assets/css/ dan file main.css:

/* assets/css/main.css */

/* Import Tailwind directives */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Base layer - style dasar */
@layer base {
  body {
    @apply antialiased text-gray-900 bg-white leading-relaxed;
  }
  
  h1, h2, h3, h4, h5, h6 {
    @apply font-bold tracking-tight text-gray-900;
  }
  
  h1 {
    @apply text-4xl md:text-5xl lg:text-6xl;
  }
  
  h2 {
    @apply text-3xl md:text-4xl;
  }
  
  h3 {
    @apply text-2xl md:text-3xl;
  }
  
  p {
    @apply mb-4;
  }
  
  a {
    @apply text-primary-600 hover:text-primary-800 transition-colors;
  }
  
  img {
    @apply max-w-full h-auto rounded-lg;
  }
}

/* Components layer - reusable components */
@layer components {
  .btn {
    @apply px-4 py-2 rounded-lg font-medium transition-all duration-200;
  }
  
  .btn-primary {
    @apply btn bg-primary-600 text-white hover:bg-primary-700;
  }
  
  .btn-secondary {
    @apply btn bg-gray-200 text-gray-800 hover:bg-gray-300;
  }
  
  .card {
    @apply bg-white rounded-xl shadow-md p-6 hover:shadow-lg transition-shadow;
  }
  
  .prose-custom {
    @apply prose prose-lg max-w-none prose-headings:font-bold prose-a:text-primary-600;
  }
}

/* Utilities layer - custom utilities */
@layer utilities {
  .text-shadow {
    text-shadow: 0 2px 4px rgba(0,0,0,0.1);
  }
  
  .bg-gradient-primary {
    @apply bg-gradient-to-r from-primary-500 to-primary-700;
  }
}

Step 5: Integrasi dengan Hugo Templates

Edit atau buat layouts/partials/head.html:

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} | {{ .Site.Title }}{{ end }}</title>
  
  <!-- Hugo Pipes: Process CSS dengan PostCSS -->
  {{ $css := resources.Get "css/main.css" }}
  {{ if $css }}
    {{ $css = $css | resources.PostCSS }}
    
    {{ if hugo.IsProduction }}
      {{ $css = $css | resources.Minify | resources.Fingerprint "sha512" }}
      <link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}" crossorigin="anonymous">
    {{ else }}
      <link rel="stylesheet" href="{{ $css.RelPermalink }}">
    {{ end }}
  {{ end }}
  
  <!-- Meta tags SEO -->
  <meta name="description" content="{{ .Description | default .Site.Params.description }}">
  <meta name="author" content="{{ .Site.Params.author }}">
  
  <!-- Open Graph -->
  <meta property="og:title" content="{{ .Title }}">
  <meta property="og:description" content="{{ .Description }}">
  <meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}">
  <meta property="og:url" content="{{ .Permalink }}">
  {{ with .Params.image }}
  <meta property="og:image" content="{{ . | absURL }}">
  {{ end }}
</head>

Penjelasan Hugo Pipes:

  • resources.Get: Mengambil file dari folder assets/
  • resources.PostCSS: Memproses CSS dengan PostCSS (menjalankan Tailwind + Autoprefixer)
  • resources.Minify: Compress CSS untuk production
  • resources.Fingerprint: Menambahkan hash untuk cache busting

Step 6: Update Hugo Configuration

Tambahkan di hugo.toml:

[build]
  writeStats = true  # Penting untuk Tailwind JIT mode

[imaging]
  quality = 80
  resampleFilter = "lanczos"

[minify]
  disableCSS = false
  disableHTML = false
  disableJS = false

Development Workflow

Mode Development

# Terminal 1: Hugo server
hugo server -D --bind 0.0.0.0

# Terminal 2: Watch Tailwind (opsional jika Hugo tidak auto-reload CSS)
npx tailwindcss -i ./assets/css/main.css -o ./static/css/output.css --watch

Tapi dengan Hugo Pipes, Anda cukup:

hugo server -D

Hugo akan otomatis:

  1. Watch file changes
  2. Re-process CSS dengan PostCSS
  3. Live reload browser

Mode Production

# Set environment variable
export HUGO_ENVIRONMENT=production

# Build dengan minification
hugo --gc --minify

# Cek ukuran file CSS
du -h public/css/*.css

Advanced Configuration

Dark Mode Support

Update tailwind.config.js:

module.exports = {
  darkMode: 'class', // atau 'media'
  // ... rest of config
}

Update CSS:

@layer base {
  body {
    @apply antialiased text-gray-900 bg-white;
    @apply dark:text-gray-100 dark:bg-gray-900;
  }
}

Toggle dark mode dengan JavaScript:

// assets/js/darkmode.js
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;

themeToggle?.addEventListener('click', () => {
  html.classList.toggle('dark');
  localStorage.setItem('theme', html.classList.contains('dark') ? 'dark' : 'light');
});

// Check saved preference
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
  html.classList.add('dark');
}

Custom Fonts dengan Tailwind

  1. Download atau CDN: Saya sarankan menggunakan Google Fonts atau self-host

  2. Update tailwind.config.js:

module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
        display: ['Cal Sans', 'Inter', 'sans-serif'],
      },
    },
  },
}
  1. Load fonts di head.html:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">

Container Queries (Modern CSS)

Install plugin:

npm install -D @tailwindcss/container-queries

Update config:

module.exports = {
  plugins: [
    require('@tailwindcss/container-queries'),
  ],
}

Penggunaan:

<div class="@container">
  <div class="@lg:grid-cols-3">
    <!-- Responsive berdasarkan container, bukan viewport -->
  </div>
</div>

Optimasi Production

Bundle Size Analysis

Install plugin:

npm install -D @tailwindcss/typography

Analisis bundle:

# Build dan cek ukuran
hugo --minify
ls -lh public/css/

# Gunakan PurgeCSS lebih agresif jika perlu

Critical CSS

Extract critical CSS untuk above-the-fold content:

{{ $critical := resources.Get "css/critical.css" | resources.PostCSS | resources.Minify }}
<style>{{ $critical.Content | safeCSS }}</style>

<!-- Load non-critical CSS async -->
<link rel="preload" href="{{ $css.RelPermalink }}" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="{{ $css.RelPermalink }}"></noscript>

Preload Font Files

<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>

Troubleshooting

CSS Tidak Ter-apply

Ceklist:

  1. ✅ Hugo Extended terinstall
  2. resources.PostCSS di template
  3. content paths di tailwind.config.js benar
  4. ✅ File CSS di assets/css/ bukan static/
  5. ✅ Restart Hugo server setelah config changes

Build Failed: “PostCSS not found”

Solusi:

# Pastikan node_modules terinstall
npm install

# Cek Hugo version (harus extended)
hugo version | grep extended

# Jika tidak extended, install ulang:
# macOS
brew uninstall hugo && brew install hugo

# Windows
choco uninstall hugo && choco install hugo-extended

Tailwind Classes Not Generated

Debug:

  1. Cek content paths:

    content: [
      './layouts/**/*.html',      // Pastikan path benar
      './content/**/*.md',        // Periksa semua content
      './themes/**/layouts/**/*.html',  // Jika pakai theme
    ],
    
  2. Verifikasi JIT mode aktif:

    module.exports = {
      mode: 'jit',  // atau pastikan Tailwind v3+
      // ...
    }
    
  3. Cek classes yang ditulis:

    <!-- Benar -->
    <div class="flex items-center justify-center">
    
    <!-- Salah (typo) -->
    <div class="flexx item-center">
    

Slow Build Time

Optimasi:

# Gunakan --disableFastRender untuk development cepat
hugo server --disableFastRender

# Atau --gc untuk garbage collection
hugo server --gc

Update tailwind.config.js:

module.exports = {
  content: [
    // Hanya include file yang perlu di-scan
    './layouts/**/*.html',
    './content/**/*.md',
    // Hindari: './node_modules/**/*' (bikin lambat)
  ],
}

Testing dan Validasi

1. Visual Regression Testing

Gunakan tools seperti:

  • Percy
  • Chromatic
  • BackstopJS

2. Accessibility Testing

# Install axe-core
npm install -D @axe-core/cli

# Test
npx axe http://localhost:1313

3. Performance Testing

  • Lighthouse: Chrome DevTools > Lighthouse
  • WebPageTest: webpagetest.org
  • PageSpeed Insights: developers.google.com/speed/pagespeed/insights

Best Practices

1. Utility-First Approach

<!-- ✅ Benar: Utility classes -->
<div class="flex items-center justify-between p-4 bg-white shadow rounded-lg">
  <h1 class="text-2xl font-bold text-gray-900">Judul</h1>
  <button class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
    Action
  </button>
</div>

<!-- ❌ Hindari: Custom CSS yang panjang -->
<div class="custom-card">
  <h1 class="custom-title">Judul</h1>
  <button class="custom-button">Action</button>
</div>

2. Extract Components untuk Reusability

Gunakan @apply untuk komponen yang sering dipakai:

@layer components {
  .btn {
    @apply px-4 py-2 rounded-lg font-medium transition-all duration-200;
  }
  
  .btn-primary {
    @apply btn bg-primary-600 text-white hover:bg-primary-700 focus:ring-2 focus:ring-primary-500;
  }
}

3. Responsive Design Mobile-First

<!-- Mobile-first: default untuk mobile, override untuk desktop -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  <!-- 1 kolom di mobile, 2 di tablet, 3 di desktop -->
</div>

<!-- Padding responsive -->
<div class="p-4 md:p-6 lg:p-8">
  <!-- Padding bertambah di device lebih besar -->
</div>

4. Semantic HTML dengan Tailwind

<!-- ✅ Semantic + Tailwind -->
<article class="prose prose-lg max-w-none">
  <header class="mb-8">
    <h1 class="text-4xl font-bold text-gray-900">{{ .Title }}</h1>
    <time class="text-gray-500" datetime="{{ .Date.Format "2006-01-02" }}">
      {{ .Date.Format "2 January 2006" }}
    </time>
  </header>
  
  <div class="prose-content">
    {{ .Content }}
  </div>
</article>

Kesimpulan

Integrasi Tailwind CSS dengan Hugo melalui PostCSS memberikan workflow development yang modern dan efisien:

Kecepatan Development: Utility classes mempercepat styling
Ukuran File Kecil: JIT mode hanya generate class yang dipakai
Konsistensi: Design system built-in
Responsif: Mobile-first approach
Customizable: Extend sesuai kebutuhan brand

Dengan setup yang benar, Anda akan mendapatkan CSS bundle yang ter-optimasi otomatis untuk production tanpa effort manual.

Artikel Terkait

Link Postingan : https://www.tirinfo.com/tutorial-tailwind-hugo-postcss/

Hendra WIjaya
Tirinfo
8 minutes.
3 February 2026