Skip to main content

Version: 3.10.x

a7-plugin-redirect

Overview

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.

When to Use

  • Enforce HTTPS by redirecting all HTTP requests
  • Redirect old URLs to new locations (301 permanent redirect)
  • Pattern-based URI rewrites using regex capture groups
  • Redirect to external domains
  • Append or preserve query strings during redirects

Plugin Configuration Reference (Route/Service)

FieldTypeRequiredDefaultDescription
http_to_httpsbooleanNofalseRedirect HTTP to HTTPS. Preserves URI and query string. Uses 301 status.
uristringNoTarget redirect URI. Supports Nginx variables ($uri, $host, etc.). Can be absolute URL.
regex_uriarray[string]NoTwo-element array: ["regex_pattern", "replacement"]. PCRE regex with capture groups.
ret_codeintegerNo302HTTP status code for the redirect response.
encode_uribooleanNofalseEncode the URI in the Location header per RFC 3986.
append_query_stringbooleanNofalseAppend 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).

HTTPS Port Selection (for http_to_https)

When http_to_https is true, the HTTPS port is determined by priority:

  1. plugin_attr.redirect.https_port in conf/config.yaml
  2. Random port from apisix.ssl.listen (if SSL configured)
  3. Default: 443

Step-by-Step: Enable redirect on a Route

1. HTTP to HTTPS redirect

Force HTTPS for gateway group default:

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "force-https",
"uri": "/*",
"plugins": {
"redirect": {
"http_to_https": true
}
}
}
EOF

Result: http://example.com/path?q=1https://example.com/path?q=1 (301)

2. Simple URI redirect (moved permanently)

a7 route create --gateway-group prod -f - <<'EOF'
{
"id": "old-to-new",
"uri": "/old-page",
"plugins": {
"redirect": {
"uri": "/new-page",
"ret_code": 301
}
}
}
EOF

3. Regex-based redirect with capture groups

a7 route create --gateway-group stage -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

Common Patterns

Redirect to external domain

{
"plugins": {
"redirect": {
"uri": "https://new-domain.com/api/v2",
"ret_code": 301
}
}
}

Redirect with Nginx variables

{
"plugins": {
"redirect": {
"uri": "https://new-domain.com$request_uri",
"ret_code": 301
}
}
}

Preserves the full original path and query string.

Append trailing slash

{
"plugins": {
"redirect": {
"uri": "$uri/",
"ret_code": 301
}
}
}

Redirect with query string preservation

{
"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

Encode special characters in URI

{
"plugins": {
"redirect": {
"uri": "/path with spaces/resource",
"encode_uri": true,
"ret_code": 302
}
}
}

Location header: /path%20with%20spaces/resource

Temporary redirect (302) for maintenance

{
"plugins": {
"redirect": {
"uri": "/maintenance.html",
"ret_code": 302
}
}
}

Use 302 (temporary) so browsers don't cache the redirect.

Troubleshooting

SymptomCauseFix
Redirect loopRoute matches the redirect targetEnsure the target URI doesn't match the same route
Wrong HTTPS portDefault port selectionSet plugin_attr.redirect.https_port in config.yaml
Query string lostUsing uri without append_query_stringAdd "append_query_string": true or use $request_uri
Duplicate query stringappend_query_string with $request_uriDon't combine both — $request_uri already includes query string
Nginx variable emptyVariable doesn't existNon-existent variables resolve to empty string (no error)
Regex not matchingEscaping or pattern issueEscape backslashes in JSON: \\d+. Test regex with PCRE syntax.
Multiple redirect options sethttp_to_https, uri, regex_uri are mutually exclusiveUse only ONE of the three options
Config not appliedWrong gateway group specifiedEnsure --gateway-group matches the desired cluster

Config Sync Example

version: "1"
gateway_group: default
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

This page is generated from a7-plugin-redirect/SKILL.md in the api7/a7 repository. Browse all skills on the AI Agent Skills page.

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation