skills/a6-plugin-redirect/SKILL.md
Skill for configuring the Apache APISIX redirect plugin via the a6 CLI. Covers URI redirects, HTTP-to-HTTPS redirection, regex-based URI rewriting, query string handling, and common operational patterns.
npx skillsauth add moonming/a6 a6-plugin-redirectInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The redirect plugin sends HTTP redirect responses (301, 302, etc.) to
clients. It can redirect to a new URI, enforce HTTPS, or use regex patterns
for complex path transformations. Unlike proxy-rewrite (which rewrites
before forwarding to upstream), this plugin returns a redirect response
directly to the client.
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| http_to_https | boolean | No | false | Redirect HTTP to HTTPS. Preserves URI and query string. Uses 301 status. |
| uri | string | No | — | Target redirect URI. Supports Nginx variables ($uri, $host, etc.). Can be absolute URL. |
| regex_uri | array[string] | No | — | Two-element array: ["regex_pattern", "replacement"]. PCRE regex with capture groups. |
| ret_code | integer | No | 302 | HTTP status code for the redirect response. |
| encode_uri | boolean | No | false | Encode the URI in the Location header per RFC 3986. |
| append_query_string | boolean | No | false | Append the original request query string to the redirect Location. |
Mutual exclusion: Only ONE of http_to_https, uri, or regex_uri can be configured at a time.
Note: http_to_https and append_query_string cannot be used together (http_to_https already preserves query strings).
When http_to_https is true, the HTTPS port is determined by priority:
plugin_attr.redirect.https_port in conf/config.yamlapisix.ssl.listen (if SSL configured)443a6 route create -f - <<'EOF'
{
"id": "force-https",
"uri": "/*",
"plugins": {
"redirect": {
"http_to_https": true
}
}
}
EOF
Result: http://example.com/path?q=1 → https://example.com/path?q=1 (301)
a6 route create -f - <<'EOF'
{
"id": "old-to-new",
"uri": "/old-page",
"plugins": {
"redirect": {
"uri": "/new-page",
"ret_code": 301
}
}
}
EOF
a6 route create -f - <<'EOF'
{
"id": "regex-redirect",
"uri": "/blog/*",
"plugins": {
"redirect": {
"regex_uri": ["^/blog/(\\d{4})/(\\d{2})/(.*)$", "/articles/$1-$2-$3"],
"ret_code": 301
}
}
}
EOF
Result: /blog/2024/03/my-post → /articles/2024-03-my-post
{
"plugins": {
"redirect": {
"uri": "https://new-domain.com/api/v2",
"ret_code": 301
}
}
}
{
"plugins": {
"redirect": {
"uri": "https://new-domain.com$request_uri",
"ret_code": 301
}
}
}
Preserves the full original path and query string.
{
"plugins": {
"redirect": {
"uri": "$uri/",
"ret_code": 301
}
}
}
{
"plugins": {
"redirect": {
"uri": "/new-path",
"append_query_string": true,
"ret_code": 302
}
}
}
Request: /old-path?foo=bar&baz=1 → Location: /new-path?foo=bar&baz=1
{
"plugins": {
"redirect": {
"uri": "/path with spaces/resource",
"encode_uri": true,
"ret_code": 302
}
}
}
Location header: /path%20with%20spaces/resource
{
"plugins": {
"redirect": {
"uri": "/maintenance.html",
"ret_code": 302
}
}
}
Use 302 (temporary) so browsers don't cache the redirect.
| Symptom | Cause | Fix |
|---------|-------|-----|
| Redirect loop | Route matches the redirect target | Ensure the target URI doesn't match the same route |
| Wrong HTTPS port | Default port selection | Set plugin_attr.redirect.https_port in config.yaml |
| Query string lost | Using uri without append_query_string | Add "append_query_string": true or use $request_uri |
| Duplicate query string | append_query_string with $request_uri | Don't combine both — $request_uri already includes query string |
| Nginx variable empty | Variable doesn't exist | Non-existent variables resolve to empty string (no error) |
| Regex not matching | Escaping or pattern issue | Escape backslashes in JSON: \\d+. Test regex with PCRE syntax. |
| Multiple redirect options set | http_to_https, uri, regex_uri are mutually exclusive | Use only ONE of the three options |
version: "1"
routes:
- id: force-https
uri: /*
plugins:
redirect:
http_to_https: true
- id: old-blog-redirect
uri: /blog/*
plugins:
redirect:
regex_uri:
- "^/blog/(\\d{4})/(\\d{2})/(.*)"
- "/articles/$1-$2-$3"
ret_code: 301
tools
Core skill for working with the a6 CLI — the Apache APISIX command-line tool. Provides project conventions, command patterns, architecture overview, and development workflow. Load this skill when working on a6 source code, adding new commands, writing tests, or modifying any a6 component.
tools
Recipe skill for implementing multi-tenant API gateway patterns using the a6 CLI. Covers tenant isolation via Consumer Groups, host/path/header-based routing, per-tenant rate limiting, context forwarding with proxy-rewrite, and declarative config sync workflows for multi-tenant management.
tools
Recipe skill for configuring mutual TLS (mTLS) using the a6 CLI. Covers SSL certificate management, upstream mTLS to backend services, client certificate verification, and end-to-end mTLS setup from client through APISIX to upstream.
tools
Recipe skill for configuring upstream health checks using the a6 CLI. Covers active health checks (HTTP probing), passive health checks (response analysis), combining both, configuring healthy/unhealthy thresholds, and monitoring upstream node status.