This episode dissects matchers in Caddy: the concept of request criteria, standard matchers like path, method, header, host, query, and remote_ip, inline and named syntax, path matching with prefixes, wildcards, and regex, plus advanced matcher combinations.

Matchers are the heart of routing in Caddy. Without matchers, every directive applies to all requests. With matchers, you can say: "only proxy POST requests to /api", "only redirect visitors from outside the country", or "only process .php files". Episode 11 dissects matchers thoroughly.
Matchers evaluate request properties: path, method, header, host, and others. A simple example — handle only POST:
example.com {
@post {
method POST
}
respond @post "This is a POST request" 200
}Example: a matcher with the method OR:
@metode {
method POST
method PUT
}The most frequently used matchers:
@api {
path /api/*
method GET POST
}
example.com {
handle @api {
reverse_proxy localhost:8080
}
handle {
root * /var/www
file_server
}
}Other commonly used matchers:
@bot {
header User-Agent *curl*
}
@internal {
remote_ip 192.168.1.0/24 10.0.0.0/8
}
example.com {
respond @bot "Hello bot!" 403
handle @internal {
respond "Internal access"
}
}For more complex patterns, use regex:
@versi {
path_regexp ^/v[0-9]+/
}
example.com {
handle @versi {
reverse_proxy localhost:9000
}
}path_regexp ^/v[0-9]+/ matches paths like /v1/users. Regex requires proper escaping — you'll see advanced usage in episode 12.
path /api/users matches only that exact path.path /api/* matches everything starting with /api/.path *.php matches all paths ending in .php.path /files/* matches everything under /files/.Suffix example:
example.com {
@php {
path *.php
}
handle @php {
php_fastcgi unix//run/php/php-fpm.sock
}
}A named matcher is reused across many directives in a single site block:
example.com {
@protected {
path /admin/*
}
handle @protected {
basicauth * {
admin $2y$10$hash
}
file_server
}
handle {
file_server
}
}For conditions you can't write with standard matchers, use expr:
example.com {
@kondisi {
expr request.method == 'GET' && path('/dashboard/*')
}
respond @kondisi "Dashboard" 200
}expr request.method == 'GET' is a CEL expression that evaluates the request programmatically. This is an advanced feature for complex routing logic.
Episode 11 equipped you with matchers: the concept of request criteria and conditional execution, standard matchers like path, method, header, host, query, and remote_ip, inline and named syntax, path matching with exact, prefix, suffix, and regex, plus AND, OR, and CEL expression combinations.
Key takeaways:
path /api/* for prefixes, path *.php for suffixes.remote_ip uses CIDR notation.@name can be reused.expr opens up complex routing logic with CEL.In the next episode, episode 12, we'll cover URI manipulation & rewriting — the rewrite and uri directives, stripping and prepending prefixes, clean URLs, variables and placeholders, regex capture groups, and try_files patterns for SPA and PHP routing. Routing will become your main weapon.