This is an automated email from the ASF dual-hosted git repository.

moonming pushed a commit to branch fix/dead-url-redirects
in repository https://gitbox.apache.org/repos/asf/apisix-website.git

commit 9c44847a682768cf044fa84208501e3523b2c9ac
Author: Ming Wen <[email protected]>
AuthorDate: Mon Jul 13 15:11:51 2026 +0800

    fix: repair dead-URL redirects and add 301s for removed doc versions
    
    Sourced from the Matomo 404 inventory (2026-06-14..07-11, 11,401
    Page-Not-Found visits) with every URL re-verified against the live site:
    
    - Retarget the version-less ingress-controller rules that still pointed
      at 1.8.0 — those pages are no longer built, so the rules themselves
      were generating 404s (incl. hijacking the real /FAQ/ and /upgrade/
      pages that exist again in the 2.x IA).
    - Strip the version segment from removed sub-project doc versions
      (ingress-controller 0.x/1.x, docker apisix-*/apisix-dashboard-*,
      apisix 2.1-2.5); renamed pages chain onto the retargeting rules.
    - Redirect removed dashboard docs to /docs/apisix/dashboard/.
    - Send bare landing directories that 403 (no index) to real entry pages.
    - Fix /docs/apisix/stand-alone and a GitHub-style path.
    
    Verified with a local httpd (mod_alias + this .htaccess): 89 of 92
    currently-broken URLs now terminate at a live 200 page within 2 hops,
    zero redirect loops, and a 38-URL control set of live pages passes
    through untouched.
---
 .htaccess | 71 ++++++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 47 insertions(+), 24 deletions(-)

diff --git a/.htaccess b/.htaccess
index 6e3e0cc22bc..f35f792f4a2 100644
--- a/.htaccess
+++ b/.htaccess
@@ -77,31 +77,28 @@ Redirect 301 
"/zh/blog/2021/11/30/use-apisix-ingress-in-kubesphere/httpbin.org/"
 Redirect 301 "/zh/blog/2021/08/25/Auth-with-Casbin-in-Apache-APISIX/" 
"/zh/blog/2021/08/18/auth-with-casbin-in-apache-apisix/"
 Redirect 301 "/zh/blog/2022/03/02/apisix-integration-graphql-plugin/" 
"/zh/blog/2022/03/02/apisix-integration-graphql/"
 
-Redirect 301 "/docs/ingress-controller/concepts/apisix_route/" 
"/docs/ingress-controller/1.8.0/concepts/apisix_route/"
-Redirect 301 "/docs/ingress-controller/concepts/apisix_upstream/" 
"/docs/ingress-controller/1.8.0/concepts/apisix_upstream/"
-Redirect 301 "/docs/ingress-controller/concepts/apisix_plugin_config/" 
"/docs/ingress-controller/1.8.0/concepts/apisix_plugin_config/"
-Redirect 301 "/docs/ingress-controller/concepts/apisix_tls/" 
"/docs/ingress-controller/1.8.0/concepts/apisix_tls/"
-Redirect 301 "/docs/ingress-controller/concepts/annotations/" 
"/docs/ingress-controller/1.8.0/concepts/annotations/"
-Redirect 301 "/docs/ingress-controller/concepts/apisix_consumer/" 
"/docs/ingress-controller/1.8.0/concepts/apisix_consumer/"
-Redirect 301 "/docs/ingress-controller/concepts/apisix_cluster_config/" 
"/docs/ingress-controller/1.8.0/concepts/apisix_cluster_config/"
-Redirect 301 "/docs/ingress-controller/concepts/apisix_global_rule/" 
"/docs/ingress-controller/1.8.0/concepts/apisix_global_rule/"
-Redirect 301 "/docs/ingress-controller/design/" 
"/docs/ingress-controller/1.8.0/design/"
-Redirect 301 "/docs/ingress-controller/composite/" 
"/docs/ingress-controller/1.8.0/composite/"
-Redirect 301 "/docs/ingress-controller/references/apisix_route_v2/" 
"/docs/ingress-controller/1.8.0/references/apisix_route_v2/"
-Redirect 301 "/docs/ingress-controller/references/apisix_upstream/" 
"/docs/ingress-controller/1.8.0/references/apisix_upstream/"
-Redirect 301 "/docs/ingress-controller/references/v2/" 
"/docs/ingress-controller/1.8.0/references/v2/"
-Redirect 301 "/docs/ingress-controller/references/apisix_tls_v2/" 
"/docs/ingress-controller/1.8.0/references/apisix_tls_v2/"
-Redirect 301 "/docs/ingress-controller/references/apisix_consumer_v2/" 
"/docs/ingress-controller/1.8.0/references/apisix_consumer_v2/"
-Redirect 301 "/docs/ingress-controller/references/apisix_route_v2beta3/" 
"/docs/ingress-controller/1.8.0/references/apisix_route_v2beta3/"
-RedirectMatch 301 "^/docs/ingress-controller/tutorials/(.*)$" 
"/docs/ingress-controller/1.8.0/tutorials/$1"
-Redirect 301 "/docs/ingress-controller/monitoring/" 
"/docs/ingress-controller/1.8.0/monitoring/"
-Redirect 301 "/docs/ingress-controller/plugins/prometheus/" 
"/docs/ingress-controller/1.8.0/plugins/prometheus/"
-RedirectMatch 301 "^/docs/ingress-controller/deployments/(.*)$" 
"/docs/ingress-controller/1.8.0/deployments/$1"
-Redirect 301 "/docs/ingress-controller/aeps/gateway-api/" 
"/docs/ingress-controller/1.8.0/aeps/gateway-api/"
-Redirect 301 "/docs/ingress-controller/contribute/" 
"/docs/ingress-controller/1.8.0/contribute/"
+# Ingress-controller pages from the pre-2.0 IA. These used to redirect to
+# 1.8.0, but only the newest release is built now, so 1.8.0 URLs 404 —
+# retarget to the closest page in the current IA. Keep these BEFORE the
+# generic version-stripping rules below: stripped old-version URLs land on
+# these paths as their second hop.
+RedirectMatch 301 
"^(/zh)?/docs/ingress-controller/concepts/(apisix_route|apisix_upstream|apisix_plugin_config|apisix_tls|apisix_consumer|apisix_cluster_config|apisix_global_rule)/$"
 "$1/docs/ingress-controller/reference/apisix-ingress-controller/api-reference/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/concepts/annotations/$" 
"$1/docs/ingress-controller/reference/apisix-ingress-controller/annotation/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/design/$" 
"$1/docs/ingress-controller/concepts/deployment-architecture/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/composite/$" 
"$1/docs/ingress-controller/overview/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/references/(.+)$" 
"$1/docs/ingress-controller/reference/apisix-ingress-controller/api-reference/"
+RedirectMatch 301 
"^(/zh)?/docs/ingress-controller/tutorials/proxy-the-httpbin-service(-with-ingress)?/$"
 "$1/docs/ingress-controller/getting-started/configure-routes/"
+RedirectMatch 301 
"^(/zh)?/docs/ingress-controller/tutorials/proxy-grpc-service/$" 
"$1/docs/ingress-controller/getting-started/configure-routes/"
+RedirectMatch 301 
"^(/zh)?/docs/ingress-controller/tutorials/enable-authentication-and-restriction/$"
 "$1/docs/ingress-controller/getting-started/key-authentication/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/tutorials/the-hard-way/$" 
"$1/docs/ingress-controller/getting-started/get-apisix-ingress-controller/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/tutorials/(.+)$" 
"$1/docs/ingress-controller/overview/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/monitoring/$" 
"$1/docs/ingress-controller/overview/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/plugins/prometheus/$" 
"$1/docs/ingress-controller/overview/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/deployments/(.+)$" 
"$1/docs/ingress-controller/install/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/aeps/gateway-api/$" 
"$1/docs/ingress-controller/concepts/gateway-api/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/contribute/$" 
"$1/docs/ingress-controller/developer-guide/"
 Redirect 301 
"/docs/ingress-controller/reference/apisix-ingress-controller/crd-reference/" 
"/docs/ingress-controller/reference/apisix-ingress-controller/api-reference/"
-Redirect 301 "/docs/ingress-controller/FAQ/" 
"/docs/ingress-controller/1.8.0/FAQ/"
-Redirect 301 "/docs/ingress-controller/upgrade/" 
"/docs/ingress-controller/1.8.0/upgrade/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/upgrade/$" 
"$1/docs/ingress-controller/upgrade-guide/"
 
 Redirect 301 "/docs/ingress-controller/next/tutorials/the-hard-way/" 
"/docs/ingress-controller/getting-started/get-apisix-ingress-controller/"
 Redirect 301 
"/docs/ingress-controller/next/tutorials/configure-ingress-with-gateway-api/" 
"/docs/ingress-controller/concepts/gateway-api/"
@@ -141,3 +138,29 @@ RedirectMatch 301 "^/docs/general/code-samples/?$" "/"
 RedirectMatch 301 "^/zh/docs/general/code-samples/?$" "/zh/"
 RedirectMatch 301 "^/help/?$" "/"
 RedirectMatch 301 "^/zh/help/?$" "/zh/"
+
+# --- Dead-URL cleanup (sourced from Matomo 404 inventory, 2026-06-14..07-11) 
---
+
+# Old sub-project doc versions are no longer built (only the newest release is
+# published) — strip the version segment. Renamed pages then land on the
+# retargeting rules above as a second hop. The apisix project itself is NOT
+# covered here: its 3.10+ versions are still built, and 2.x/3.x legacy
+# redirects for it are handled at the infra layer.
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/[01]\.\d+\.\d+/(.+)$" 
"$1/docs/ingress-controller/$2"
+RedirectMatch 301 
"^(/zh)?/docs/docker/(?:apisix-(?:dashboard-)?)?\d+\.\d+(?:\.\d+)?/(.+)$" 
"$1/docs/docker/$2"
+RedirectMatch 301 "^(/zh)?/docs/apisix/2\.[1-5](?:\.\d+)?/(.+)$" 
"$1/docs/apisix/$2"
+
+# Dashboard docs were removed from the site entirely
+RedirectMatch 301 "^(/zh)?/docs/dashboard(/.*)?$" "$1/docs/apisix/dashboard/"
+
+# Bare landing directories have no index page and return 403 — send visitors
+# to the real entry pages instead
+RedirectMatch 301 "^(/zh)?/docs/apisix/$" 
"$1/docs/apisix/getting-started/README/"
+RedirectMatch 301 "^(/zh)?/docs/apisix/plugins/$" "$1/plugins/"
+RedirectMatch 301 "^(/zh)?/docs/apisix/3\.\d+/getting-started/$" 
"$1/docs/apisix/getting-started/README/"
+RedirectMatch 301 "^(/zh)?/docs/ingress-controller/$" 
"$1/docs/ingress-controller/overview/"
+RedirectMatch 301 
"^(/zh)?/docs/ingress-controller/(?:next/)?getting-started/$" 
"$1/docs/ingress-controller/getting-started/get-apisix-ingress-controller/"
+
+# Renamed docs and GitHub-repo-style paths that leak into search results
+RedirectMatch 301 "^(/zh)?/docs/apisix/stand-alone/?$" 
"$1/docs/apisix/deployment-modes/"
+RedirectMatch 301 "^(/zh)?/docs/apisix/en/latest/deployment-modes(\.md)?/?$" 
"$1/docs/apisix/deployment-modes/"

Reply via email to