Migrasi dari WordPress ke Hugo adalah keputusan yang bagus untuk performa, security, dan cost efficiency. Tutorial ini akan membimbing Anda melalui seluruh proses migrasi step-by-step.
Mengapa Migrasi dari WordPress ke Hugo?
Perbandingan WordPress vs Hugo
| Aspek | WordPress | Hugo |
|---|---|---|
| Hosting | Server + Database required | Static hosting (CDN) |
| Security | Vulnerabilities, plugins | No database, no server-side code |
| Speed | Depends on hosting | <1s loading time |
| Cost | $5-50+/month | Free or $0-5/month |
| Maintenance | Regular updates required | Minimal |
| Scale | Cache required untuk high traffic | CDN handles scale automatically |
| SEO | Plugin dependent | Built-in optimization |
Benefits Migrasi ke Hugo
- Kecepatan: Static site = instant loading
- Security: No database = no SQL injection
- Cost: Free hosting di banyak platform
- Reliability: CDN = 99.99% uptime
- Version Control: Semua content di Git
- Developer Experience: Markdown + Git workflow
Pre-Migration Planning
1. Audit WordPress Site
Content Inventory:
# List semua posts dan pages
# Gunakan plugin: Export to Markdown atau manual export
Check:
- Total posts
- Total pages
- Custom post types
- Categories dan tags
- Media files
- Comments
- Users
Plugin untuk Export:
- WordPress to Jekyll Exporter (works untuk Hugo)
- WP Static HTML Output
- Simply Static
- Static HTML Output
2. URL Structure Planning
Match atau Redirect?
WordPress URL: /2024/02/03/hello-world/
Hugo URL: /blog/hello-world/
Decision:
- Keep same: /:year/:month/:day/:slug/
- New structure: /:slug/
- Redirect old URLs ke new
Step 1: Export Content dari WordPress
Method 1: WordPress to Jekyll Exporter
Install Plugin
– Dashboard → Plugins → Add New
– Search: “WordPress to Jekyll Exporter”
– Install dan ActivateExport
– Tools → Export to Jekyll
– Download file.zipExtract
bash
unzip jekyll-export.zip -d wordpress-export/
Method 2: Manual Export dengan WP-CLI
# Install WP-CLI jika belum
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
Export posts ke Markdown
wp post list --format=ids | xargs -I {} wp post get {} --field=content --format=json > posts.json
Atau gunakan plugin untuk bulk export
Method 3: Database Export
-- Export posts
SELECT post_title, post_content, post_date, post_name
FROM wp_posts
WHERE post_type = 'post' AND post_status = 'publish';
Step 2: Setup Hugo Project
1. Create Hugo Site
# Install Hugo jika belum
# (lihat artikel install Hugo)
Buat site baru
hugo new site my-wordpress-migration
cd my-wordpress-migration
Initialize Git
git init
Install theme
Pilih theme yang mirip dengan WordPress theme Anda
git submodule add
https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
2. Configure Hugo
hugo.toml:
baseURL = 'https://yourdomain.com'
languageCode = 'en-us'
title = 'Your Site Title'
theme = 'ananke'
Match WordPress permalink structure
[permalinks]
posts = '/:year/:month/:day/:slug/'
Preserve WordPress categories dan tags
[taxonomies]
category = 'categories'
tag = 'tags'
[params]
author = 'Your Name'
description = 'Site description'
Step 3: Convert dan Import Content
1. Convert WordPress XML ke Markdown
Gunakan tool: wordpress-to-hugo-exporter
# Clone tool
git clone https://github.com/SchumacherFM/wordpress-to-hugo-exporter.git
cd wordpress-to-hugo-exporter
Install dependencies
composer install
Export WordPress content
php hugo-export.php
2. Manual Conversion Script
Python script untuk convert:
#!/usr/bin/env python3 import re import os from datetime import datetimedef convert_wordpress_to_hugo(wp_file, output_dir): with open(wp_file, 'r', encoding='utf-8') as f: content = f.read()
# Extract title title_match = re.search(r'title: (.*)', content) title = title_match.group(1) if title_match else 'Untitled' # Extract date date_match = re.search(r'date: (\d{4}-\d{2}-\d{2})', content) date_str = date_match.group(1) if date_match else datetime.now().strftime('%Y-%m-%d') # Create frontmatter frontmatter = f"""---title: "{title}"
date: {date_str}T00:00:00+00:00
draft: false"""
# Clean WordPress content body = re.sub(r'---.*?---', '', content, flags=re.DOTALL) body = clean_wordpress_content(body) # Write to file slug = re.sub(r'[^\w\s-]', '', title).strip().lower() slug = re.sub(r'[-\s]+', '-', slug) output_file = os.path.join(output_dir, f"{date_str}-{slug}.md") with open(output_file, 'w', encoding='utf-8') as f: f.write(frontmatter + body) print(f"Created: {output_file}")def clean_wordpress_content(content):
Remove WordPress-specific tags
content = re.sub(r'\[.*?\]', '', content) # Shortcodes content = re.sub(r'<!--.*?-->', '', content, flags=re.DOTALL) # Comments # Convert HTML ke Markdown jika perlu # atau keep HTML yang valid return content.strip()Usage
convert_wordpress_to_hugo('wordpress-post.txt', 'content/posts/')
3. Import ke Hugo
# Copy converted files cp -r wordpress-export/content/* my-hugo-site/content/Organize structure
mkdir -p content/posts content/pages mv content/20 content/posts/ # Move dated posts mv content/page- content/pages/ # Move pages
4. Fix Frontmatter
Batch fix dengan script:
#!/bin/bash # fix-frontmatter.shfor file in content/posts/*.md; do
Add description jika tidak ada
if ! grep -q "^description:" "$file"; then sed -i 's/^---$/---\ndescription: ""/g' "$file" fi
Add categories jika tidak ada
if ! grep -q "^categories:" "$file"; then sed -i 's/^---$/---\ncategories: []/g' "$file" fi done
Step 4: Handle Media Files
1. Export Media dari WordPress
# Download all media files # Option 1: Gunakan plugin "Export Media Library"Option 2: Manual download
wget --mirror --convert-links --adjust-extension \ --page-requisites --no-parent \ https://yourwordpresssite.com/wp-content/uploads/
2. Organize di Hugo
# Move ke Hugo static folder mkdir -p static/images/wp-content mv wordpress-uploads/* static/images/wp-content/Optimize images (opsional)
Gunakan Hugo image processing atau tools seperti ImageMagick
3. Update Image URLs
Script untuk replace URLs:
#!/usr/bin/env python3 import re import osdef update_image_urls(directory): for root, dirs, files in os.walk(directory): for file in files: if file.endswith('.md'): filepath = os.path.join(root, file)
with open(filepath, 'r', encoding='utf-8') as f: content = f.read() # Replace WordPress URLs dengan Hugo URLs content = re.sub( r'https?://[^\s\"]+/wp-content/uploads/(\d{4})/(\d{2})/([^\s\"]+)', r'/images/wp-content/\1/\2/\3', content ) with open(filepath, 'w', encoding='utf-8') as f: f.write(content) print(f"Updated: {filepath}")update_image_urls('content/')
Step 5: Setup Redirects
1. Create Redirects File
static/_redirects (untuk Netlify):
# Redirect old WordPress URLs ke Hugo URLs /blog/:year/:month/:day/:slug/ /posts/:slug/ 301 /category/:name/ /categories/:name/ 301 /tag/:name/ /tags/:name/ 301 /author/:name/ /authors/:name/ 301 /feed/ /index.xml 301 /wp-content/uploads/* /images/wp-content/:splat 301static/.htaccess (untuk Apache):
RewriteEngine OnRedirect WordPress posts
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})/([^/]+)/?$ /posts/$4/ [R=301,L]
Redirect categories
RewriteRule ^category/([^/]+)/?$ /categories/$1/ [R=301,L]
Redirect tags
RewriteRule ^tag/([^/]+)/?$ /tags/$1/ [R=301,L]
2. Generate Redirects dari WordPress
Script untuk extract URLs:
#!/usr/bin/env python3 import redef generate_redirects(wp_export_file): redirects = []
# Read WordPress export with open(wp_export_file, 'r') as f: content = f.read() # Extract post URLs post_urls = re.findall(r'https?://[^\s\"]+/\d{4}/\d{2}/\d{2}/([^/\s\"]+)', content) for slug in post_urls: old_url = f"/20*/20*/20*/{slug}/" new_url = f"/posts/{slug}/" redirects.append(f"{old_url} {new_url} 301") # Write to file with open('static/_redirects', 'w') as f: f.write('\n'.join(redirects)) print(f"Generated {len(redirects)} redirects")generate_redirects('wordpress-export.xml')
Step 6: Handle Comments
Option 1: Static Comments (Export)
# Export comments dari WordPress # Gunakan plugin "Export Comments to JSON"Convert ke static HTML atau YAML
Option 2: Third-party Comments
Disqus:
<!-- layouts/partials/comments.html --> {{ if .Site.Params.disqus }} <div id="disqus_thread"></div> <script> var disqus_config = function () { this.page.url = "{{ .Permalink }}"; this.page.identifier = "{{ .RelPermalink }}"; }; (function() { var d = document, s = d.createElement('script'); s.src = 'https://{{ .Site.Params.disqus }}.disqus.com/embed.js'; s.setAttribute('data-timestamp', +new Date()); (d.head || d.body).appendChild(s); })(); </script> {{ end }}Utterances (GitHub-based):
<script src="https://utteranc.es/client.js" repo="username/repo" issue-term="pathname" theme="github-light" crossorigin="anonymous" async> </script>Step 7: Build dan Test
1. Build Hugo Site
# Development mode hugo server -DProduction build
hugo --gc --minify
2. Test Checklist
# Content tests - [ ] Semua posts muncul - [ ] Semua pages muncul - [ ] Categories dan tags work - [ ] Images load correctly - [ ] Internal links workFunctionality tests
- [ ] Search works
- [ ] Navigation works
- [ ] Pagination works
- [ ] RSS feed valid
- [ ] Sitemap valid
SEO tests
- [ ] Meta titles correct
- [ ] Meta descriptions present
- [ ] Open Graph tags work
- [ ] Twitter Cards work
- [ ] Canonical URLs correct
- [ ] Redirects work
Performance tests
- [ ] Lighthouse score > 90
- [ ] Page size < 1MB
- [ ] Loading time < 3s
3. Compare dengan WordPress
Before/After Comparison:
# WordPress metrics (before) Page size: 2.5MB Load time: 4.2s Lighthouse: 65/100Hugo metrics (after)
Page size: 0.4MB Load time: 0.8s Lighthouse: 95/100
Step 8: Deploy
Deploy ke Cloudflare Pages
# .github/workflows/deploy.yml name: Deploy Hugo on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: peaceiris/actions-hugo@v2 with: hugo-version: 'latest' extended: true - run: hugo --gc --minify - uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./publicDNS Configuration
Update DNS Records
– Point domain ke CDN (Cloudflare/Netlify)
– Setup SSL/TLS
– Configure redirectsTest DNS Propagation
# Check DNS dig yourdomain.com nslookup yourdomain.comTest dari berbagai lokasi
Gunakan tools: whatsmydns.net
Post-Migration Tasks
1. Update Search Engines
# Submit sitemap baru ke Google Search Console # Check for crawl errors # Monitor 404 errors # Update robots.txt jika perlu2. Monitor Traffic
# Check analytics untuk drop traffic # Monitor 404 errors di console # Fix broken links3. Clean Up
# Backup WordPress files # Export database untuk archive # Cancel WordPress hosting # Update bookmarks/documentationTroubleshooting Migration
Issue: “Images Not Loading”
Solusi:
# Check image paths grep -r "wp-content/uploads" content/Fix dengan sed
sed -i 's|/wp-content/uploads/|/images/wp-content/|g' content/* /.md
Issue: “Broken Links”
Solusi:
# Find broken links grep -r "http://olddomain.com" content/Replace dengan new domain
sed -i 's|http://olddomain.com|https://newdomain.com|g' content/* /.md
Issue: “Comments Missing”
Solusi:
– Export comments ke JSON
– Convert ke static HTML
– Atau gunakan third-party serviceIssue: “SEO Ranking Drop”
Solusi:
1. Pastikan redirects 301 benar
2. Submit sitemap baru
3. Request reindex di Search Console
4. Monitor 404 errors
5. Update internal linksKesimpulan
Migrasi WordPress ke Hugo memberikan:
✅ 60-80% reduction dalam page size
✅ 3-5x faster loading times
✅ Near-zero maintenance
✅ Better security (no database)
✅ Lower costs (free hosting options)
✅ Version control untuk contentTimeline migrasi: 1-2 minggu untuk site medium (100-500 posts)
Ditulis oleh
Hendra Wijaya