Redirect #
Redirect memberitahu browser (dan search engine) bahwa sebuah URL telah berpindah ke URL lain. Berbeda dari rewrite yang terjadi secara internal, redirect mengirimkan response HTTP dengan status code 3xx dan header Location, lalu browser melakukan request baru ke URL tujuan.
Caddy menyediakan direktif redir untuk redirect yang bersih dan ekspresif, serta handler static_response untuk kasus yang lebih kompleks.
Status Code Redirect #
301 Moved Permanently
→ URL lama tidak ada lagi, URL baru adalah permanent
→ Search engine transfer link juice ke URL baru
→ Browser meng-cache redirect (kunjungan berikutnya langsung ke URL baru)
→ Gunakan untuk: migrasi domain, perubahan URL permanen
302 Found (Temporary Redirect)
→ URL lama masih valid, sementara menggunakan URL lain
→ Search engine TIDAK transfer link juice
→ Browser TIDAK meng-cache redirect
→ Gunakan untuk: maintenance, A/B testing sementara
303 See Other
→ Redirect ke resource lain setelah POST/PUT (Post/Redirect/Get pattern)
→ Gunakan untuk: form submission, mencegah double submit
307 Temporary Redirect
→ Seperti 302 tapi mempertahankan HTTP method (POST tetap POST)
→ Gunakan untuk: temporary redirect yang perlu preserve method
308 Permanent Redirect
→ Seperti 301 tapi mempertahankan HTTP method
→ Gunakan untuk: permanent redirect yang perlu preserve method
Sintaks Dasar redir
#
example.com {
# Redirect ke URL lain (default: 302 temporary)
redir /lama /baru
# Dengan status code eksplisit
redir /lama /baru 301
redir /lama /baru 302
redir /lama /baru permanent # Alias untuk 301
redir /lama /baru temporary # Alias untuk 302
}
Redirect HTTP ke HTTPS #
Ini adalah konfigurasi yang paling umum — Caddy sebenarnya melakukan ini secara otomatis, tapi berguna dipahami untuk konfigurasi eksplisit:
# Cara Caddy melakukan redirect HTTP ke HTTPS secara otomatis
# (terjadi di balik layar ketika kamu menulis domain.com { ... })
# Eksplisit jika perlu custom behavior
http://example.com {
redir https://example.com{uri} 301
}
https://example.com {
root * /var/www/html
file_server
}
www ke Non-www (dan Sebaliknya) #
# Redirect www ke non-www (lebih umum)
www.example.com {
redir https://example.com{uri} 301
}
example.com {
root * /var/www/html
file_server
}
# Atau: redirect non-www ke www
example.com {
redir https://www.example.com{uri} 301
}
www.example.com {
root * /var/www/html
file_server
}
Redirect Berdasarkan Path #
example.com {
# Redirect path lama ke path baru
redir /about-us /about 301
redir /contact-us /contact 301
redir /blog/old-post /blog/new-post 301
# Redirect dengan mempertahankan query string
redir /search /find{uri} 301
# /search?q=caddy → /find?q=caddy
root * /var/www/html
file_server
}
Redirect Berbasis Regex #
Untuk redirect yang memerlukan pattern matching:
example.com {
# Redirect format URL lama ke format baru
# /products/123 → /shop/items/123
@old-products path_regexp ^/products/(\d+)$
redir @old-products /shop/items/{re.1} 301
# Redirect semua file .php ke path tanpa ekstensi
@php path_regexp ^(.+)\.php$
redir @php {re.1} 301
# /about.php → /about
# Redirect trailing slash (optional - Caddy kadang handle otomatis)
@trailing path_regexp ^(.+)/$
redir @trailing {re.1} 301
# /about/ → /about
file_server { root /var/www/html }
}
Redirect Domain Lama ke Domain Baru #
Ketika kamu migrasi dari domain lama ke domain baru:
# Domain lama — redirect semua ke domain baru
old-domain.com www.old-domain.com {
redir https://new-domain.com{uri} 301
}
# Domain baru — serving normal
new-domain.com {
root * /var/www/html
file_server
}
Bulk Redirect dari File #
Untuk banyak URL yang perlu di-redirect (misalnya setelah migrasi CMS besar):
example.com {
# Import daftar redirect dari file terpisah
# Format di dalam file: redir /old /new 301
import /etc/caddy/redirects.conf
root * /var/www/html
file_server
}
# /etc/caddy/redirects.conf
# Satu redirect per baris
redir /about-us /about 301
redir /blog/2023 /archive/2023 301
redir /old-product /products/new-product 301
redir /contact-us /contact 301
Redirect Berdasarkan Kondisi Lain #
example.com {
# Redirect berdasarkan header (misalnya: redirect mobile ke mobile site)
@mobile {
header User-Agent *Mobile*
not header User-Agent *iPad*
}
redir @mobile https://m.example.com{uri} 302
# Redirect berdasarkan query parameter
@old-format query format=old
redir @old-format {path} 302
# Hapus query parameter format=old
file_server { root /var/www/html }
}
Redirect Sementara untuk Maintenance #
# Saat maintenance: redirect semua ke halaman maintenance
# Ganti konfigurasi ini saat maintenance selesai
example.com {
@not-maintenance not path /maintenance.html
redir @not-maintenance /maintenance.html 302
# Aset statis tetap bisa diakses
@assets path *.css *.js *.png *.ico
handle @assets {
root * /var/www/html
file_server
}
handle {
root * /var/www/html
file_server
}
}
Debug Redirect Chain #
# Cek redirect chain dengan curl
curl -Lsv https://www.example.com/old-path 2>&1 | grep -E "Location:|< HTTP"
# Output contoh:
# < HTTP/1.1 301 Moved Permanently
# Location: https://example.com/old-path
# < HTTP/1.1 301 Moved Permanently
# Location: https://example.com/new-path
# < HTTP/1.1 200 OK
# Cek berapa redirect yang terjadi
curl -o /dev/null -s -L -w "%{num_redirects}\n" https://www.example.com/
# Pastikan tidak ada redirect loop!
# Redirect loop terjadi jika A → B → A → B → ...
# Browser biasanya menghentikan setelah 20 redirect
Redirect Seluruh Site ke Domain Baru dengan Preservasi Path #
# Skenario: berganti nama dari old-company.com ke new-company.com
# Pertahankan semua path dan query string
old-company.com www.old-company.com {
# {uri} mencakup path DAN query string sekaligus
redir https://new-company.com{uri} 301
# Contoh:
# old-company.com/products?id=123
# → new-company.com/products?id=123
}
new-company.com {
reverse_proxy backend:3000
}
Redirect Trailing Slash #
example.com {
# Tambah trailing slash ke direktori
# /blog → /blog/ (jika /blog/ adalah direktori)
# Atau sebaliknya — hapus trailing slash dari non-direktori
@trailing path_regexp ^(.+[^/])/+$
redir @trailing {re.1} 301
# /about/ → /about
# /products/ → /products
file_server { root /var/www/html }
}
Ringkasan #
- Gunakan 301 Permanent untuk redirect permanen (domain migration, URL cleanup) — search engine akan transfer link equity dan browser meng-cache redirect.
- Gunakan 302 Temporary untuk redirect sementara (maintenance, A/B test) — search engine tidak mengubah index, browser tidak meng-cache.
redir /lama /baru 301adalah sintaks paling simpel — Caddy otomatis mempertahankan query string jika kamu menggunakan{uri}di tujuan.- Untuk migrasi domain, konfigurasikan domain lama sepenuhnya untuk redirect ke domain baru dengan
redir https://new-domain.com{uri} 301.- Redirect regex menggunakan
path_regexpmatcher dan{re.N}untuk capture groups — powerful untuk transformasi URL yang kompleks.- Selalu test redirect chain dengan
curl -Lsvuntuk memastikan tidak ada redirect loop atau redirect yang terlalu panjang.
← Sebelumnya: Rewrite Berikutnya: Encode →
Redirect untuk SEO: Menangani Duplikat Konten #
Duplikat konten bisa merusak SEO. Gunakan redirect untuk mengkonsolidasikan URL:
example.com {
# Hapus parameter UTM sebelum redirect ke canonical
# (UTM parameter berguna untuk analytics tapi bisa buat duplikat di Google)
@has-utm query utm_source=* utm_medium=* utm_campaign=*
redir @has-utm {path} 301
# /products?utm_source=email&utm_medium=newsletter → /products
# Normalisasi uppercase ke lowercase di path
# (Caddy tidak punya built-in untuk ini, tapi bisa dengan rewrite + handler)
root * /var/www/html
file_server
}
Redirect Saat Pindah ke Subdomain #
# Pindah blog dari /blog ke subdomain blog.example.com
example.com {
@blog path /blog/*
redir @blog https://blog.example.com{path} 301
# /blog/hello-world → https://blog.example.com/hello-world
root * /var/www/html
file_server
}
blog.example.com {
reverse_proxy blog-backend:4000
}
Redirect ini mempertahankan path setelah /blog/ dan memindahkannya ke subdomain, ideal saat memisahkan blog ke platform terpisah.
Redirect vs Handle: Memilih yang Tepat #
example.com {
# REDIRECT: gunakan saat URL lama benar-benar tidak digunakan lagi
# Browser dan search engine akan update index mereka
redir /old-blog/* /new-blog/{path} 301
# REWRITE: gunakan saat kamu ingin URL internal berbeda tapi URL publik sama
# Browser tetap melihat URL asli
rewrite /clean-url /actual-file.php
# HANDLE: gunakan saat routing berbeda ke handler berbeda
# Tidak ada perubahan URL, hanya logika pemrosesan berbeda
handle /api/* {
reverse_proxy api:8080
}
}
Memilih antara ketiganya bergantung pada: apakah URL publik harus berubah (redirect), apakah path internal berbeda dari yang terlihat (rewrite), atau apakah kamu hanya perlu routing ke handler berbeda (handle).