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

Yilialinn pushed a commit to branch codex/technical-mobile-seo
in repository https://gitbox.apache.org/repos/asf/apisix-website.git

commit 23ea0695684afe70e1f83c4e3dd75dcab8efa407
Author: Yilia Lin <[email protected]>
AuthorDate: Tue Jun 16 15:33:44 2026 +0800

    Improve technical SEO and mobile performance
---
 blog/en/docusaurus.config.js                   |   8 ++
 blog/src/css/customTheme.scss                  |  55 ++++++++++++
 blog/src/theme/CodeBlock/styles.module.css     |   9 ++
 blog/src/theme/NotFound/index.tsx              |  20 +++--
 blog/zh/docusaurus.config.js                   |   8 ++
 config/ssrTemplate.js                          |  41 ++++++---
 doc/docusaurus.config.js                       |   8 ++
 doc/src/css/customTheme.scss                   |  55 ++++++++++++
 doc/src/pages/edit.tsx                         |   2 +-
 doc/src/theme/CodeBlock/styles.module.css      |   9 ++
 doc/src/theme/NotFound/index.tsx               |  20 +++--
 seo_technical_mobile_changes.csv               |  15 ++++
 seo_technical_mobile_followup_items.csv        |  15 ++++
 seo_technical_mobile_implementation_summary.md | 115 +++++++++++++++++++++++++
 seo_technical_mobile_review_checklist.md       |  43 +++++++++
 website/docusaurus.config.js                   |   8 +-
 website/src/components/AIGateway/AvifImage.tsx |  10 ++-
 website/src/components/AIGateway/Hero.tsx      |   3 +-
 website/src/components/HeroCanvas.tsx          |  15 ++--
 website/src/css/customTheme.scss               |  55 ++++++++++++
 website/src/css/landing-sections/hero.scss     |  49 ++++++++++-
 website/src/pages/ai-gateway.tsx               |   9 ++
 website/src/pages/index.tsx                    |   4 +
 website/src/theme/NotFound/index.tsx           |  20 +++--
 website/static/robots.txt                      |  14 +++
 25 files changed, 562 insertions(+), 48 deletions(-)

diff --git a/blog/en/docusaurus.config.js b/blog/en/docusaurus.config.js
index f07832c66e1..93003060185 100644
--- a/blog/en/docusaurus.config.js
+++ b/blog/en/docusaurus.config.js
@@ -15,10 +15,18 @@ const metadatas = [
     name: 'robots',
     content: 'index,follow',
   },
+  {
+    property: 'og:site_name',
+    content: 'Apache APISIX',
+  },
   {
     name: 'twitter:card',
     content: 'summary_large_image',
   },
+  {
+    name: 'twitter:site',
+    content: '@apacheapisix',
+  },
 ];
 
 module.exports = {
diff --git a/blog/src/css/customTheme.scss b/blog/src/css/customTheme.scss
index 6a330ec0073..f220effa6cb 100644
--- a/blog/src/css/customTheme.scss
+++ b/blog/src/css/customTheme.scss
@@ -526,3 +526,58 @@ button[class*="announcementBarClose"] {
     font-weight: 500;
   }
 }
+
+/* stylelint-disable no-descending-specificity */
+.markdown img,
+article img {
+  max-width: 100%;
+  height: auto;
+}
+
+.markdown table {
+  display: block;
+  max-width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.markdown pre {
+  max-width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+h1,
+h2,
+h3,
+[id] {
+  scroll-margin-top: calc(var(--ifm-navbar-height) + 16px);
+}
+
+@media screen and (max-width: 996px) {
+  article {
+    font-size: 17px;
+    line-height: 1.75;
+  }
+
+  article p {
+    font-size: 17px;
+    line-height: 1.75;
+  }
+
+  article h1 {
+    font-size: 2.1rem;
+    line-height: 1.15;
+  }
+
+  article h2 {
+    font-size: 1.75rem;
+    line-height: 1.2;
+  }
+
+  article h3 {
+    font-size: 1.35rem;
+    line-height: 1.25;
+  }
+}
+/* stylelint-enable no-descending-specificity */
diff --git a/blog/src/theme/CodeBlock/styles.module.css 
b/blog/src/theme/CodeBlock/styles.module.css
index 707a187e50e..9a9e1705c3b 100644
--- a/blog/src/theme/CodeBlock/styles.module.css
+++ b/blog/src/theme/CodeBlock/styles.module.css
@@ -17,6 +17,8 @@
 .codeBlockContent {
   position: relative;
   direction: ltr;
+  max-width: 100%;
+  overflow-x: auto;
 }
 
 .codeBlockTitle {
@@ -30,6 +32,7 @@
   margin: 0;
   padding: 0;
   border-radius: 0;
+  min-width: 100%;
 }
 
 .copyButton {
@@ -65,3 +68,9 @@
     white-space: pre-wrap;
   }
 }
+
+@media (hover: none) {
+  .copyButton {
+    opacity: 1;
+  }
+}
diff --git a/blog/src/theme/NotFound/index.tsx 
b/blog/src/theme/NotFound/index.tsx
index f8c6490bf6d..c8a513b32b1 100644
--- a/blog/src/theme/NotFound/index.tsx
+++ b/blog/src/theme/NotFound/index.tsx
@@ -2,6 +2,7 @@
 import type { FC } from 'react';
 import React from 'react';
 import Layout from '@theme/Layout';
+import Head from '@docusaurus/Head';
 import { translate } from '@docusaurus/Translate';
 import Link from '@docusaurus/Link';
 import style from './styles.module.scss';
@@ -14,6 +15,9 @@ const NotFound: FC = () => (
       message: 'Page Not Found',
     })}
   >
+    <Head>
+      <meta name="robots" content="noindex,follow" />
+    </Head>
     <main className={style.container}>
       <section>
         <Fitty tagName="h1" contentEditable>404</Fitty>
@@ -31,12 +35,16 @@ const NotFound: FC = () => (
         .
       </p>
       <p>
-        You can also return to
+        You can also open the
         {' '}
-        <Link href="/">
-          the home page
-        </Link>
-        . Or, return to
+        <Link to="/">home page</Link>
+        ,
+        {' '}
+        <Link to="/docs/">documentation</Link>
+        ,
+        {' '}
+        <Link to="/blog/">blog</Link>
+        , or
         {' '}
         <a
           role="button"
@@ -45,7 +53,7 @@ const NotFound: FC = () => (
             window?.history.back();
           }}
         >
-          the source page
+          return to the source page
         </a>
         .
       </p>
diff --git a/blog/zh/docusaurus.config.js b/blog/zh/docusaurus.config.js
index 3af01760c79..23d6b7b915b 100644
--- a/blog/zh/docusaurus.config.js
+++ b/blog/zh/docusaurus.config.js
@@ -16,10 +16,18 @@ const metadatas = [
     name: 'robots',
     content: 'index,follow',
   },
+  {
+    property: 'og:site_name',
+    content: 'Apache APISIX',
+  },
   {
     name: 'twitter:card',
     content: 'summary_large_image',
   },
+  {
+    name: 'twitter:site',
+    content: '@apacheapisix',
+  },
 ];
 
 module.exports = {
diff --git a/config/ssrTemplate.js b/config/ssrTemplate.js
index 7edf02dd6eb..8bd22cd7d32 100644
--- a/config/ssrTemplate.js
+++ b/config/ssrTemplate.js
@@ -6,6 +6,11 @@ module.exports = {
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <meta name="ahrefs-site-verification" 
content="c2f7370ecf46173f4fb25f114e74c97e0a2976d4f02f61c9b00a9d7d34e34698">
       <meta name="generator" content="Docusaurus v<%= it.version %>">
+      <link rel="preconnect" href="https://static.apiseven.com"; crossorigin>
+      <link rel="preconnect" href="https://apisix-website-static.apiseven.com"; 
crossorigin>
+      <link rel="preconnect" href="https://static.api7.ai"; crossorigin>
+      <link rel="dns-prefetch" href="https://analytics.apache.org";>
+      <link rel="dns-prefetch" href="https://widget.kapa.ai";>
       <% if (it.noIndex) { %>
         <meta name="robots" content="noindex, nofollow" />
       <% } %>
@@ -22,21 +27,29 @@ module.exports = {
       <% }); %>
       <!-- Matomo from the ASF -->
       <script>
-        var _paq = window._paq = window._paq || [];
-        /* tracker methods like "setCustomDimension" should be called before
+        window._paq = window._paq || [];
+        function loadMatomo() {
+          var _paq = window._paq;
+          /* tracker methods like "setCustomDimension" should be called before
       "trackPageView" */
-        /* We explicitly disable cookie tracking to avoid privacy issues */
-        _paq.push(['disableCookies']);
-        _paq.push(['trackPageView']);
-        _paq.push(['enableLinkTracking']);
-        (function() {
-          var u="https://analytics.apache.org/";;
-          _paq.push(['setTrackerUrl', u+'matomo.php']);
-          _paq.push(['setSiteId', '17']);
-          var d=document, g=d.createElement('script'),
-      s=d.getElementsByTagName('script')[0];
-          g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
-        })();
+          /* We explicitly disable cookie tracking to avoid privacy issues */
+          _paq.push(['disableCookies']);
+          _paq.push(['trackPageView']);
+          _paq.push(['enableLinkTracking']);
+          (function() {
+            var u="https://analytics.apache.org/";;
+            _paq.push(['setTrackerUrl', u+'matomo.php']);
+            _paq.push(['setSiteId', '17']);
+            var d=document, g=d.createElement('script'),
+        s=d.getElementsByTagName('script')[0];
+            g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
+          })();
+        }
+        if ('requestIdleCallback' in window) {
+          window.requestIdleCallback(loadMatomo, { timeout: 3000 });
+        } else {
+          window.addEventListener('load', loadMatomo, { once: true });
+        }
       </script>
       <!-- End Matomo Code -->
     </head>
diff --git a/doc/docusaurus.config.js b/doc/docusaurus.config.js
index 80324e4e15d..ef8c7e8d008 100644
--- a/doc/docusaurus.config.js
+++ b/doc/docusaurus.config.js
@@ -251,10 +251,18 @@ module.exports = {
         name: 'robots',
         content: 'index,follow',
       },
+      {
+        property: 'og:site_name',
+        content: 'Apache APISIX',
+      },
       {
         name: 'twitter:card',
         content: 'summary_large_image',
       },
+      {
+        name: 'twitter:site',
+        content: '@apacheapisix',
+      },
     ],
   },
   scripts: [
diff --git a/doc/src/css/customTheme.scss b/doc/src/css/customTheme.scss
index 26ecfa5e636..dfa1d0d3df3 100644
--- a/doc/src/css/customTheme.scss
+++ b/doc/src/css/customTheme.scss
@@ -524,3 +524,58 @@ button[class*="announcementBarClose"] {
     font-weight: 500;
   }
 }
+
+/* stylelint-disable no-descending-specificity */
+.markdown img,
+article img {
+  max-width: 100%;
+  height: auto;
+}
+
+.markdown table {
+  display: block;
+  max-width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.markdown pre {
+  max-width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+h1,
+h2,
+h3,
+[id] {
+  scroll-margin-top: calc(var(--ifm-navbar-height) + 16px);
+}
+
+@media screen and (max-width: 996px) {
+  article {
+    font-size: 17px;
+    line-height: 1.75;
+  }
+
+  article p {
+    font-size: 17px;
+    line-height: 1.75;
+  }
+
+  article h1 {
+    font-size: 2.1rem;
+    line-height: 1.15;
+  }
+
+  article h2 {
+    font-size: 1.75rem;
+    line-height: 1.2;
+  }
+
+  article h3 {
+    font-size: 1.35rem;
+    line-height: 1.25;
+  }
+}
+/* stylelint-enable no-descending-specificity */
diff --git a/doc/src/pages/edit.tsx b/doc/src/pages/edit.tsx
index 2914c8291b4..c9a14bda71f 100644
--- a/doc/src/pages/edit.tsx
+++ b/doc/src/pages/edit.tsx
@@ -57,7 +57,7 @@ const Edit: FC = () => {
         />
         <meta name="twitter:site" content="@apacheapisix" />
         <meta
-          name="og:description"
+          property="og:description"
           content="Apache APISIX is a dynamic, real-time, high-performance 
Cloud-Native API gateway, based on the Nginx library and etcd."
         />
       </Head>
diff --git a/doc/src/theme/CodeBlock/styles.module.css 
b/doc/src/theme/CodeBlock/styles.module.css
index 707a187e50e..9a9e1705c3b 100644
--- a/doc/src/theme/CodeBlock/styles.module.css
+++ b/doc/src/theme/CodeBlock/styles.module.css
@@ -17,6 +17,8 @@
 .codeBlockContent {
   position: relative;
   direction: ltr;
+  max-width: 100%;
+  overflow-x: auto;
 }
 
 .codeBlockTitle {
@@ -30,6 +32,7 @@
   margin: 0;
   padding: 0;
   border-radius: 0;
+  min-width: 100%;
 }
 
 .copyButton {
@@ -65,3 +68,9 @@
     white-space: pre-wrap;
   }
 }
+
+@media (hover: none) {
+  .copyButton {
+    opacity: 1;
+  }
+}
diff --git a/doc/src/theme/NotFound/index.tsx b/doc/src/theme/NotFound/index.tsx
index f8c6490bf6d..c8a513b32b1 100644
--- a/doc/src/theme/NotFound/index.tsx
+++ b/doc/src/theme/NotFound/index.tsx
@@ -2,6 +2,7 @@
 import type { FC } from 'react';
 import React from 'react';
 import Layout from '@theme/Layout';
+import Head from '@docusaurus/Head';
 import { translate } from '@docusaurus/Translate';
 import Link from '@docusaurus/Link';
 import style from './styles.module.scss';
@@ -14,6 +15,9 @@ const NotFound: FC = () => (
       message: 'Page Not Found',
     })}
   >
+    <Head>
+      <meta name="robots" content="noindex,follow" />
+    </Head>
     <main className={style.container}>
       <section>
         <Fitty tagName="h1" contentEditable>404</Fitty>
@@ -31,12 +35,16 @@ const NotFound: FC = () => (
         .
       </p>
       <p>
-        You can also return to
+        You can also open the
         {' '}
-        <Link href="/">
-          the home page
-        </Link>
-        . Or, return to
+        <Link to="/">home page</Link>
+        ,
+        {' '}
+        <Link to="/docs/">documentation</Link>
+        ,
+        {' '}
+        <Link to="/blog/">blog</Link>
+        , or
         {' '}
         <a
           role="button"
@@ -45,7 +53,7 @@ const NotFound: FC = () => (
             window?.history.back();
           }}
         >
-          the source page
+          return to the source page
         </a>
         .
       </p>
diff --git a/seo_technical_mobile_changes.csv b/seo_technical_mobile_changes.csv
new file mode 100644
index 00000000000..be0a28b5f62
--- /dev/null
+++ b/seo_technical_mobile_changes.csv
@@ -0,0 +1,15 @@
+"Priority","Workstream","Issue","Action Taken","Files Changed","Expected SEO 
Impact","Review Notes"
+"P0","Mobile Core Web Vitals","Mobile LCP risk on homepage hero due animated 
first-viewport text and full-height layout","Disabled hero entrance animation 
on mobile/reduced-motion, switched to mobile min-height with svh, added 
responsive clamp sizing and 
wrapping","website/src/css/landing-sections/hero.scss","Improve mobile 
first-content readability and reduce LCP/perceived LCP delay","Check homepage 
mobile visual layout around 360px, 390px, 768px, and desktop"
+"P0","Performance / INP","Head analytics script competes with critical 
rendering work","Delayed Matomo loading using requestIdleCallback with load 
fallback","config/ssrTemplate.js","Reduce initial main-thread and network 
pressure during LCP window","Confirm analytics stakeholders accept delayed 
pageview initialization"
+"P0","Performance / LCP","Critical static asset domains had no explicit early 
connection hints","Added preconnect for static asset domains and dns-prefetch 
for analytics/widget domains","config/ssrTemplate.js","Reduce connection setup 
latency for fonts/static assets and third-party scripts","Verify generated head 
includes the new hints once in built HTML"
+"P0","AI Gateway LCP","AI Gateway hero image could inherit lazy behavior from 
shared image component","Set AI Gateway hero image to eager and reserved 
minimum hero image height","website/src/components/AIGateway/Hero.tsx","Protect 
likely LCP image from accidental lazy loading and reduce layout shift","Check 
hero image does not create too much blank space on mobile"
+"P1","Image Loading","Shared AI Gateway image component lacked default 
loading/decoding behavior","Added default loading=lazy and decoding=async while 
allowing callers to 
override","website/src/components/AIGateway/AvifImage.tsx","Improve 
non-critical image loading and browser decoding behavior","Confirm Chakra Image 
passes loading/decoding to img output"
+"P1","Rendering Performance","Hero WebGL canvas rendered at full 
devicePixelRatio and did not remove listeners on unmount","Capped renderer 
pixel ratio at 1.5 and removed resize/mousemove listeners during 
cleanup","website/src/components/HeroCanvas.tsx","Reduce GPU/render cost and 
avoid listener leaks affecting interactions","Check desktop hero animation 
still looks acceptable on Retina screens"
+"P1","Mobile UX / CLS","Docs/blog/main content images, tables, and code blocks 
can overflow mobile viewport","Added mobile-safe image, table, pre, article 
typography, and anchor offset rules across website/doc/blog 
themes","website/src/css/customTheme.scss; doc/src/css/customTheme.scss; 
blog/src/css/customTheme.scss","Reduce horizontal overflow, improve mobile 
reading, reduce layout instability","Review docs/blog article typography on 
mobile and desktop"
+"P1","Mobile Docs UX","Code block copy button depended on hover and long code 
could be awkward on touch devices","Added max-width/overflow handling and 
visible copy button on hoverless 
devices","doc/src/theme/CodeBlock/styles.module.css; 
blog/src/theme/CodeBlock/styles.module.css","Improve docs/blog mobile usability 
and reduce interaction friction","Check copy button does not cover important 
code on narrow screens"
+"P1","Metadata / CTR","Homepage lacked page-specific meta description and had 
malformed OG description attribute","Added homepage description and og:title; 
changed og description from name to property; normalized title 
dash","website/src/pages/index.tsx","Improve homepage snippet quality and Open 
Graph correctness","Check final rendered head has no duplicate conflicting 
descriptions"
+"P1","Metadata / Social SEO","AI Gateway page lacked social image metadata and 
used small Twitter card","Added og:image/twitter:image and summary_large_image 
Twitter card","website/src/pages/ai-gateway.tsx","Improve share preview and 
reinforce AI Gateway landing page relevance","Confirm image URL remains stable 
and public"
+"P1","Metadata / Social SEO","Default site-level social metadata was 
incomplete across website/doc/blog builds","Added og:site_name and twitter:site 
in all Docusaurus configs","website/docusaurus.config.js; 
doc/docusaurus.config.js; blog/en/docusaurus.config.js; 
blog/zh/docusaurus.config.js","Improve social metadata consistency across 
templates","Verify no conflicting site_name values in page-specific Head"
+"P1","Indexing / Soft 404","Static 404 pages could be treated as indexable 
pages in static hosting contexts","Added noindex,follow and useful recovery 
links to website/doc/blog 404 templates","website/src/theme/NotFound/index.tsx; 
doc/src/theme/NotFound/index.tsx; blog/src/theme/NotFound/index.tsx","Reduce 
404/Soft 404 index risk and improve crawl/user recovery paths","Confirm host 
still returns proper 404 status for 404.html routes"
+"P1","Indexing / Duplicate Docs","Robots blocked versioned docs through 3.15 
but current version config includes 3.16","Added 3.16 versioned docs paths to 
robots exclusions for all docs projects and zh 
equivalents","website/static/robots.txt","Reduce duplicate latest vs versioned 
docs indexing signals","Confirm maintainers agree latest unversioned docs 
should be the only indexed current docs"
+"P2","Metadata Syntax","Doc edit page used name instead of property for Open 
Graph description","Changed name=og:description to 
property=og:description","doc/src/pages/edit.tsx","Fix Open Graph metadata 
syntax","Low-risk syntax correction"
diff --git a/seo_technical_mobile_followup_items.csv 
b/seo_technical_mobile_followup_items.csv
new file mode 100644
index 00000000000..2025edbf584
--- /dev/null
+++ b/seo_technical_mobile_followup_items.csv
@@ -0,0 +1,15 @@
+"Priority","Issue","Why Not Changed Directly","Recommended Next Step","Owner"
+"P0","Crawled - currently not indexed: 2935 URLs","GSC export used for this 
task contains aggregate counts, not URL-level samples; changing 
canonical/noindex/content blindly is unsafe","Export URL samples from GSC, 
classify by page type and business value, then fix high-value docs/blog/landing 
pages first","SEO + Website"
+"P0","404: 873 URLs","No URL-level backlink/internal-link/traffic context was 
available; bulk redirects could send users and crawlers to wrong 
targets","Export 404 URL list, join with internal links and backlinks, then 
create a reviewed redirect map for valuable URLs","SEO + Website"
+"P0","Soft 404: 584 URLs","Soft 404 causes vary by URL: thin content, empty 
templates, obsolete docs, or wrong status; template-only fix would be 
risky","Sample and classify Soft 404 URLs; fix templates for systemic cases and 
redirect/remove only confirmed obsolete pages","SEO + Website"
+"P0","Full combined build did not complete in local checkout","Docs content 
was not synced, GitHub API hit rate limit, and local blog prepare did not 
create src folders under Node 26","Run full build in CI or prepared local env 
with GITHUB_TOKEN, yarn sync-docs, generated repo info, and blog prepared 
folders","Engineering"
+"P0","Isolated build reports many broken docs/blog links","The main site build 
was run without merged doc/blog outputs, so Docusaurus reported expected 
cross-part links as broken","Review broken links after full generate-website 
build with docs and blog outputs present","Engineering"
+"P1","Versioned docs indexing strategy","Robots currently blocks versioned 
docs; switching to canonical/noindex needs maintainer agreement and 
build-output validation","Decide whether versioned docs should be 
robots-blocked, noindexed, or canonicalized to latest/current equivalents","SEO 
+ Maintainers"
+"P1","Indexed though blocked by robots.txt: 629 URLs","Robots changes alone 
cannot remove already indexed blocked URLs; samples are needed to choose 
noindex/canonical/removal","Export samples and use URL inspection to decide 
whether to unblock + noindex, canonicalize, or request removal","SEO"
+"P1","Duplicate, Google chose different canonical: 537 URLs","Need sample URL 
pairs to understand whether issue comes from docs versions, language 
alternates, trailing slash, or duplicate content","Export samples and compare 
rendered canonical/hreflang in production HTML","SEO + Engineering"
+"P1","Internal links to high-opportunity pages","Several target pillar/landing 
pages are not built yet; adding links to placeholders would create broken 
links","After Task 3 content pages exist, add natural internal links from 
docs/blog/topic hubs to AI Gateway, API Security, Kubernetes, Comparison 
pages","Content + SEO"
+"P1","Kapa widget JS loads on all pages","Changing support widget loading 
behavior may affect documentation support UX; needs owner approval","Evaluate 
idle-loading or route-specific loading for Kapa widget and measure INP 
impact","Docs + Engineering"
+"P1","Mobile Core Web Vitals validation","Local code changes need field/lab 
validation on production-like build and real target URLs","Run 
Lighthouse/PageSpeed on homepage, AI Gateway, docs getting started, plugin 
docs, and high-traffic blog pages before/after deploy","SEO + Engineering"
+"P2","Hreflang/canonical output audit","Docusaurus should generate alternates, 
but this needs rendered HTML verification across website/doc/blog 
builds","Crawl built site and verify canonical, hreflang, trailing slash, and 
locale alternates for representative pages","SEO"
+"P2","Blog prepare script behavior under Node 26","Local `yarn workspace blog 
prepare-en` did not produce `blog/en/src`, blocking isolated blog build 
validation","Reproduce on CI-supported Node version; if still failing, replace 
hexo-fs copy step with a deterministic fs.cp script","Engineering"
+"P2","Browserslist and Docusaurus warnings","Build passes with warnings, but 
dependencies are old and can affect modern browser targets","Schedule 
dependency maintenance separately; do not combine with SEO implementation 
PR","Engineering"
diff --git a/seo_technical_mobile_implementation_summary.md 
b/seo_technical_mobile_implementation_summary.md
new file mode 100644
index 00000000000..6e0abc39f24
--- /dev/null
+++ b/seo_technical_mobile_implementation_summary.md
@@ -0,0 +1,115 @@
+# APISIX Technical SEO + Mobile SEO Implementation Summary
+
+## 1. Summary
+
+本次基于 APISIX SEO 报告、GSC 技术 SEO 数据和 `apache/apisix-website` 
当前代码,完成了一批可直接落地、低风险、可 review 的技术 SEO 与移动端优化。
+
+重点处理了四类问题:
+
+- 移动端 LCP / CLS 风险:减少首页移动端首屏动画阻塞,优化 AI Gateway 首屏图加载,稳定图片、表格、代码块在移动端的布局。
+- 页面体验与 INP 风险:延迟 Matomo 加载、减少首屏网络竞争、清理 HeroCanvas 事件监听并限制高 DPI WebGL 渲染开销。
+- Metadata / Social SEO:补充和修复默认站点级社交信号、首页 description、AI Gateway 分享图片、Open 
Graph 属性错误。
+- Indexing / Coverage 信号:404 页面增加 `noindex,follow`,robots 补齐 `3.16` 版本化 docs 
URL 的排除规则,减少 latest 与 versioned docs 重复索引风险。
+
+没有做高风险动作,例如批量删除页面、批量 301、批量 noindex 旧内容、大规模 URL 改写。这些已经放入 follow-up 清单。
+
+## 2. Repository Audit
+
+| Item | Finding |
+| --- | --- |
+| Repository | `/Users/api7/Documents/GitHub/contents/apisix-website` |
+| Remote | `https://github.com/apache/apisix-website.git` |
+| Branch | `pr/2028` |
+| Framework | Docusaurus v2 beta multi-workspace static site |
+| Workspaces | `website`, `doc`, `blog`, `scripts` |
+| Main build | `yarn build` -> `yarn workspace scripts generate-website` |
+| Main site config | `website/docusaurus.config.js` |
+| Docs config | `doc/docusaurus.config.js` |
+| Blog config | `blog/en/docusaurus.config.js`, `blog/zh/docusaurus.config.js` 
|
+| Head template | `config/ssrTemplate.js` |
+| Structured data | `config/schema-org.js` |
+| Robots | `website/static/robots.txt` |
+| Sitemap post-process | `scripts/update-sitemap-loc.js` |
+| Main styles | `website/src/css/customTheme.scss`, 
`doc/src/css/customTheme.scss`, `blog/src/css/customTheme.scss` |
+| Homepage | `website/src/pages/index.tsx`, 
`website/src/components/sections/HeroSection.tsx` |
+| AI Gateway page | `website/src/pages/ai-gateway.tsx`, 
`website/src/components/AIGateway/*` |
+
+## 3. Input Data Audit
+
+| File | Type | Main Content | Used For | Notes |
+| --- | --- | --- | --- | --- |
+| `/Users/api7/Documents/APISIX SEO/apisix_seo_integrated_final_report_zh.md` 
| Final SEO report | GSC, Semrush, technical SEO, opportunities | Overall 
direction | Used as the main source of priorities |
+| `/Users/api7/Documents/APISIX SEO/apisix_gsc_technical_seo_update_zh.md` | 
Technical SEO update | CWV, Coverage, Internal Links findings | Technical 
prioritization | Identified mobile LCP, indexing, internal-link risks |
+| `/Users/api7/Documents/APISIX SEO/gsc_core_web_vitals_issues.csv` | GSC CWV 
| Mobile LCP and INP issue counts | Mobile performance scope | Confirmed P0 
mobile LCP issue |
+| `/Users/api7/Documents/APISIX SEO/gsc_indexing_coverage_issues.csv` | GSC 
Coverage | Crawled not indexed, 404, Soft 404, robots, duplicate issues | 
Indexing scope | Used to decide what can and cannot be directly changed |
+| `/Users/api7/Documents/APISIX SEO/gsc_internal_link_opportunities.csv` | GSC 
internal links | High-value pages with low internal links | Follow-up planning 
| Not directly changed because target pillar pages need content decisions |
+| `/Users/api7/Documents/APISIX SEO/gsc_internal_links_top_targets.csv` | GSC 
internal links | Current internal-link distribution | Follow-up planning | Used 
to avoid adding arbitrary template links |
+| `/Users/api7/Documents/APISIX SEO/gsc_apisix_page_opportunities.csv` | GSC 
page opportunities | Page-level SEO opportunities | Page prioritization | Used 
to focus on homepage, docs, AI Gateway, high-value templates |
+
+## 4. Directly Changed
+
+| Area | What Changed | Why |
+| --- | --- | --- |
+| Head resource hints | Added `preconnect` for static asset domains and 
`dns-prefetch` for analytics/widget domains | Reduce connection setup cost for 
critical assets and third-party scripts |
+| Analytics loading | Delayed Matomo initialization via `requestIdleCallback` 
/ `load` fallback | Reduce head-script competition during LCP window |
+| Homepage metadata | Added stronger homepage `description`, fixed title 
format, added `og:title`, fixed `og:description` property | Improve default 
search/social snippet quality and fix Open Graph syntax |
+| AI Gateway metadata | Added `og:image`, `twitter:image`, changed Twitter 
card to `summary_large_image` | Improve share preview and strengthen AI Gateway 
landing-page metadata |
+| Default social metadata | Added `og:site_name` and `twitter:site` in 
website/doc/blog configs | Improve default social metadata consistency |
+| AI Gateway images | Made `AvifImage` default to lazy + async decoding; set 
hero image to eager | Avoid lazy-loading the likely LCP image while keeping 
non-critical images lazy |
+| Homepage mobile hero | Disabled hero entrance animation on 
mobile/reduced-motion, added `svh`, clamp sizing, better wrapping | Reduce 
mobile LCP delay and layout overflow risk |
+| HeroCanvas | Capped WebGL pixel ratio and removed resize/mousemove listeners 
on unmount | Reduce render cost and cleanup interaction listeners |
+| Mobile content CSS | Added image/table/pre overflow and mobile article 
typography rules in website/doc/blog | Improve docs/blog readability and reduce 
horizontal overflow / CLS risk |
+| Code blocks | Added max-width/overflow handling and visible copy button on 
touch devices | Improve mobile docs/blog usability |
+| 404 pages | Added `noindex,follow` and useful recovery links in 
website/doc/blog 404 templates | Avoid indexing static 404 pages and help 
users/crawlers recover |
+| Robots | Added `3.16` versioned docs to robots exclusions | Align robots 
with current version config and latest-only docs indexing strategy |
+| Open Graph bug | Fixed `name="og:description"` to 
`property="og:description"` | Correct OG metadata syntax |
+
+## 5. Not Directly Changed
+
+| Issue | Reason |
+| --- | --- |
+| Bulk 301 redirects for 404 URLs | GSC export did not include concrete URL 
samples with backlink/traffic context; unsafe to batch redirect blindly |
+| Soft 404 remediation | Needs URL-level classification: thin content, 
obsolete version docs, real missing page, or duplicate content |
+| Crawled currently not indexed | Needs sample URLs and page-type 
classification before changing canonical/noindex/content |
+| Versioned docs canonical strategy | Robots already blocks versioned docs; 
switching to canonical/noindex strategy needs maintainer decision |
+| Internal-link additions to pillar pages | Several recommended pillar pages 
do not exist yet; linking to placeholders would create broken links |
+| Large-scale content rewrites | Belongs to content strategy tasks, not 
low-risk technical SEO implementation |
+| Kapa widget full lazy-loading | Possible, but should be reviewed with 
docs/support owners because it changes user support behavior |
+
+## 6. Validation
+
+| Check | Result | Notes |
+| --- | --- | --- |
+| `yarn install --frozen-lockfile` | Passed after network authorization | 
First attempt failed due DNS/network restriction |
+| `git diff --check` | Passed | No whitespace errors |
+| `node --check config/ssrTemplate.js` | Passed | JS syntax valid |
+| `node --check website/docusaurus.config.js` | Passed | JS syntax valid |
+| `node --check doc/docusaurus.config.js` | Passed | JS syntax valid |
+| `node --check blog/en/docusaurus.config.js` | Passed | JS syntax valid |
+| `node --check blog/zh/docusaurus.config.js` | Passed | JS syntax valid |
+| Targeted ESLint | Passed | Checked modified TSX files |
+| Targeted Stylelint | Passed | Checked modified SCSS/CSS files; project-level 
deprecation warnings only |
+| `SHOW_BUILD_LOGS=false yarn build` | Failed due environment/prep issues | 
Full build needs docs sync and generated files; initial failure included 
sandbox write permission and missing doc sidebars |
+| `yarn build:website` | Passed after generating local ignored build fixtures 
| English and Chinese main site compiled; isolated build logs existing broken 
links because doc/blog outputs were not merged |
+
+## 7. Build Caveats
+
+The main website build passed, but the full combined build could not be 
completed cleanly in this local checkout for reasons outside this SEO 
implementation:
+
+- `doc/docs/apisix/sidebars.json` and other synced docs files are missing 
until `yarn sync-docs` is run.
+- `generate-repos-info` hit GitHub API rate limit without `GITHUB_TOKEN`.
+- `blog prepare-en/prepare-zh` did not create `blog/en/src` / `blog/zh/src` in 
this local Node 26 environment, causing isolated blog builds to miss 
`./src/css/customTheme.scss`.
+- Isolated main-site build reports broken links to docs/blog paths because 
those outputs are normally merged by the full build.
+
+These are recorded in `seo_technical_mobile_followup_items.csv`.
+
+## 8. Review Focus
+
+Reviewers should focus on:
+
+- Whether delaying Matomo until idle/load is acceptable for ASF analytics 
requirements.
+- Whether adding `3.16` versioned docs to robots matches the intended 
latest-only docs indexing strategy.
+- Mobile homepage hero visual regression on common viewports.
+- AI Gateway hero image behavior on mobile: it should be eager for the first 
viewport but still use AVIF/WebP sources.
+- 404 page `noindex,follow` behavior and recovery links.
+- Whether global mobile typography changes are acceptable for docs/blog 
readability.
diff --git a/seo_technical_mobile_review_checklist.md 
b/seo_technical_mobile_review_checklist.md
new file mode 100644
index 00000000000..e4698b3988b
--- /dev/null
+++ b/seo_technical_mobile_review_checklist.md
@@ -0,0 +1,43 @@
+# Technical SEO + Mobile SEO Review Checklist
+
+## Head And Metadata
+
+- [ ] Confirm `config/ssrTemplate.js` renders preconnect/dns-prefetch tags 
only once.
+- [ ] Confirm delayed Matomo loading still satisfies analytics expectations.
+- [ ] Confirm homepage rendered head contains the intended title, description, 
`og:title`, and `og:description`.
+- [ ] Confirm AI Gateway rendered head contains `og:image`, `twitter:image`, 
and `summary_large_image`.
+- [ ] Confirm `og:site_name` and `twitter:site` do not conflict with 
page-level metadata.
+
+## Mobile / Core Web Vitals
+
+- [ ] Test homepage at 360px, 390px, 768px, and desktop widths.
+- [ ] Confirm mobile hero text is visible immediately and does not overflow.
+- [ ] Confirm the homepage CTA still looks correct after animation changes.
+- [ ] Confirm AI Gateway hero image loads in the first viewport and does not 
create layout shift.
+- [ ] Confirm non-critical AI Gateway images still lazy-load.
+- [ ] Confirm desktop HeroCanvas still renders acceptably after pixel ratio 
cap.
+
+## Docs / Blog Mobile UX
+
+- [ ] Open a docs page with a long code block and check horizontal scrolling.
+- [ ] Open a blog post with images and verify images do not overflow on mobile.
+- [ ] Open a docs page with a table and verify horizontal scrolling is usable.
+- [ ] Check that anchor links scroll below the sticky navbar.
+- [ ] Verify copy buttons are visible on touch devices and do not cover too 
much code.
+
+## Indexing / Coverage
+
+- [ ] Confirm `404.html` includes `noindex,follow`.
+- [ ] Confirm 404 pages still return HTTP 404 in production hosting.
+- [ ] Confirm `robots.txt` 3.16 exclusions match the docs version strategy.
+- [ ] Confirm sitemap filtering still excludes versioned docs via 
`scripts/update-sitemap-loc.js`.
+- [ ] Do not merge bulk redirect/noindex changes until GSC URL samples are 
classified.
+
+## Build / QA
+
+- [ ] Run `yarn install --frozen-lockfile`.
+- [ ] Run targeted ESLint on modified TSX files.
+- [ ] Run targeted Stylelint on modified SCSS/CSS files.
+- [ ] Run `yarn build:website`.
+- [ ] In CI or a prepared local environment, run full `yarn prepare-data` / 
`yarn build` with docs and blog generated.
+- [ ] Review broken-link output only after docs/blog outputs are present in 
the merged build.
diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js
index f6211b8d4ef..0cb370dfac7 100644
--- a/website/docusaurus.config.js
+++ b/website/docusaurus.config.js
@@ -154,6 +154,10 @@ module.exports = {
         name: 'robots',
         content: 'index,follow',
       },
+      {
+        property: 'og:site_name',
+        content: 'Apache APISIX',
+      },
       {
         name: 'twitter:card',
         content: 'summary_large_image',
@@ -162,10 +166,6 @@ module.exports = {
         name: 'twitter:site',
         content: '@apacheapisix',
       },
-      {
-        property: 'og:site_name',
-        content: 'Apache APISIX',
-      },
       {
         property: 'og:type',
         content: 'website',
diff --git a/website/src/components/AIGateway/AvifImage.tsx 
b/website/src/components/AIGateway/AvifImage.tsx
index b33560b8698..0af8199cb2d 100644
--- a/website/src/components/AIGateway/AvifImage.tsx
+++ b/website/src/components/AIGateway/AvifImage.tsx
@@ -3,15 +3,21 @@ import type { ImageProps } from '@chakra-ui/react';
 import { Image } from '@chakra-ui/react';
 
 const AvifImage: React.FC<ImageProps> = ({ src, alt, ...props }) => {
+  const imageProps = {
+    decoding: 'async',
+    loading: 'lazy',
+    ...props,
+  };
+
   if (src?.toLowerCase().includes('.svg') || src?.includes('imageMogr2/')) {
-    return <Image src={src} alt={alt} {...props} />;
+    return <Image src={src} alt={alt} {...imageProps} />;
   }
 
   return (
     <picture>
       <source srcSet={`${src}?imageMogr2/format/avif`} type="image/avif" />
       <source srcSet={`${src}?imageMogr2/format/webp`} type="image/webp" />
-      <Image src={src} alt={alt} {...props} />
+      <Image src={src} alt={alt} {...imageProps} />
     </picture>
   );
 };
diff --git a/website/src/components/AIGateway/Hero.tsx 
b/website/src/components/AIGateway/Hero.tsx
index 2da332e8cdd..ea52d9313bc 100644
--- a/website/src/components/AIGateway/Hero.tsx
+++ b/website/src/components/AIGateway/Hero.tsx
@@ -59,10 +59,11 @@ const Hero: React.FC = () => {
             display="flex"
             alignItems="center"
           >
-            <Box w="full">
+            <Box w="full" minH={{ base: '260px', md: '360px' }}>
               <AvifImage
                 
src="https://static.api7.ai/uploads/2025/04/17/zdPVQ1zg_apisix-ai-gateway.png";
                 alt="Apache APISIX AI Gateway architecture overview"
+                loading="eager"
                 animation={fadeInAnimation}
                 w="full"
                 transform="scale(1.1)"
diff --git a/website/src/components/HeroCanvas.tsx 
b/website/src/components/HeroCanvas.tsx
index 32b13accfb8..fd93e4f6136 100644
--- a/website/src/components/HeroCanvas.tsx
+++ b/website/src/components/HeroCanvas.tsx
@@ -50,8 +50,6 @@ const HeroCanvas: FC = () => {
     let camera; let mesh; let scene; let renderer; let material; let
       geometry;
 
-    window.addEventListener('resize', onWindowResize, false);
-
     if (screenWidth > 1100) {
       canvasHeight = screenHeight;
       canvasWidth = screenWidth / 2;
@@ -63,7 +61,7 @@ const HeroCanvas: FC = () => {
     canvasRef.current.width = canvasWidth;
     canvasRef.current.height = canvasHeight;
 
-    canvasRef.current.addEventListener('mousemove', (event) => {
+    const handleCanvasMouseMove = (event: MouseEvent) => {
       const ctx = {
         x: (event.clientX),
         y: (event.clientY),
@@ -96,7 +94,10 @@ const HeroCanvas: FC = () => {
           material.uniforms.u_fragMouse.value.y = fragMouse.y;
         },
       });
-    });
+    };
+
+    window.addEventListener('resize', onWindowResize, false);
+    canvasRef.current.addEventListener('mousemove', handleCanvasMouseMove);
 
     function getRandom(a, b) {
       return a + (b - a) * Math.random();
@@ -114,8 +115,6 @@ const HeroCanvas: FC = () => {
         if (entry.isIntersecting && isLoaded) {
           if (isLoaded && !isRendering) {
             animate();
-          } else {
-            console.log('Loading');
           }
         } else {
           if (animationFrame) {
@@ -210,7 +209,7 @@ const HeroCanvas: FC = () => {
 
       controls.update();
 
-      renderer.setPixelRatio(window.devicePixelRatio);
+      renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 1.5));
       onWindowResize();
 
       isLoaded = true;
@@ -249,6 +248,8 @@ const HeroCanvas: FC = () => {
     }
 
     return () => {
+      window.removeEventListener('resize', onWindowResize, false);
+      canvasRef.current?.removeEventListener('mousemove', 
handleCanvasMouseMove);
       // eslint-disable-next-line prefer-spread
       scene.remove.apply(scene, scene.children);
       canvasObserver.disconnect();
diff --git a/website/src/css/customTheme.scss b/website/src/css/customTheme.scss
index 9d1950e8f7a..e12aff151cb 100644
--- a/website/src/css/customTheme.scss
+++ b/website/src/css/customTheme.scss
@@ -530,3 +530,58 @@ button[class*="announcementBarClose"] {
     font-weight: 500;
   }
 }
+
+/* stylelint-disable no-descending-specificity */
+.markdown img,
+article img {
+  max-width: 100%;
+  height: auto;
+}
+
+.markdown table {
+  display: block;
+  max-width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.markdown pre {
+  max-width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+h1,
+h2,
+h3,
+[id] {
+  scroll-margin-top: calc(var(--ifm-navbar-height) + 16px);
+}
+
+@media screen and (max-width: 996px) {
+  article {
+    font-size: 17px;
+    line-height: 1.75;
+  }
+
+  article p {
+    font-size: 17px;
+    line-height: 1.75;
+  }
+
+  article h1 {
+    font-size: 2.1rem;
+    line-height: 1.15;
+  }
+
+  article h2 {
+    font-size: 1.75rem;
+    line-height: 1.2;
+  }
+
+  article h3 {
+    font-size: 1.35rem;
+    line-height: 1.25;
+  }
+}
+/* stylelint-enable no-descending-specificity */
diff --git a/website/src/css/landing-sections/hero.scss 
b/website/src/css/landing-sections/hero.scss
index ac00c56029e..61bdaa5005f 100644
--- a/website/src/css/landing-sections/hero.scss
+++ b/website/src/css/landing-sections/hero.scss
@@ -37,7 +37,7 @@
 .hero-ctas {
   display: flex;
   align-items: center;
-  animation-delay: 0.5;
+  animation-delay: 0.5s;
 }
 
 .hero-sec-wrap {
@@ -158,3 +158,50 @@
     width: 40vw;
   }
 }
+
+@media (max-width: 996px) {
+  .hero-title,
+  .hero-subtitle,
+  .hero-ctas {
+    animation: none;
+  }
+
+  .hero-sec-wrap {
+    min-height: calc(100svh - var(--ifm-navbar-height));
+    height: auto;
+    padding: 72px 0 48px;
+  }
+
+  .hero-text {
+    width: 100%;
+    padding: 0 24px;
+    align-content: center;
+  }
+
+  .hero-title {
+    width: 100%;
+    max-width: 680px;
+    font-size: clamp(2.4rem, 12vw, 4.2rem);
+    line-height: 1.05;
+  }
+
+  .hero-subtitle {
+    width: 100%;
+    max-width: 680px;
+    padding-right: 0;
+    margin: 18px 0;
+  }
+
+  .hero-ctas {
+    flex-wrap: wrap;
+    gap: 12px;
+  }
+}
+
+@media (prefers-reduced-motion: reduce) {
+  .hero-title,
+  .hero-subtitle,
+  .hero-ctas {
+    animation: none;
+  }
+}
diff --git a/website/src/pages/ai-gateway.tsx b/website/src/pages/ai-gateway.tsx
index eb3e6d056d3..bed576b649b 100644
--- a/website/src/pages/ai-gateway.tsx
+++ b/website/src/pages/ai-gateway.tsx
@@ -30,7 +30,12 @@ const ChakraTestPage: React.FC = () => (
         property="og:description"
         content="An AI gateway manages traffic between applications and LLM 
providers. Apache APISIX AI Gateway provides LLM load balancing, token rate 
limiting, MCP support, and security for AI agents."
       />
+      <meta
+        property="og:image"
+        
content="https://static.api7.ai/uploads/2025/04/17/zdPVQ1zg_apisix-ai-gateway.png";
+      />
 
+      <meta name="twitter:card" content="summary_large_image" />
       <meta
         name="twitter:title"
         content="What is an AI Gateway? APISIX AI Gateway for LLMs &amp; AI 
Agents"
@@ -39,6 +44,10 @@ const ChakraTestPage: React.FC = () => (
         name="twitter:description"
         content="An AI gateway manages traffic between applications and LLM 
providers. Apache APISIX AI Gateway provides LLM load balancing, token rate 
limiting, MCP support, and security for AI agents."
       />
+      <meta
+        name="twitter:image"
+        
content="https://static.api7.ai/uploads/2025/04/17/zdPVQ1zg_apisix-ai-gateway.png";
+      />
 
       <script type="application/ld+json">
         {JSON.stringify({
diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx
index 2b6e6318c42..97212bb9bdd 100644
--- a/website/src/pages/index.tsx
+++ b/website/src/pages/index.tsx
@@ -49,6 +49,10 @@ const Index: FC = () => (
     <Head>
       <title>{translate({ id: 'homepage.meta.title', message: 'Apache APISIX - 
Open Source API Gateway & AI Gateway' })}</title>
       <link rel="canonical" href="https://apisix.apache.org/"; />
+      <meta
+        name="description"
+        content="Apache APISIX is a dynamic, high-performance, open-source API 
gateway and AI gateway. Features include load balancing, authentication, rate 
limiting, AI proxying, LLM load balancing, and 100+ plugins."
+      />
       <meta
         property="og:title"
         content="Apache APISIX - Open Source API Gateway &amp; AI Gateway"
diff --git a/website/src/theme/NotFound/index.tsx 
b/website/src/theme/NotFound/index.tsx
index f8c6490bf6d..c8a513b32b1 100644
--- a/website/src/theme/NotFound/index.tsx
+++ b/website/src/theme/NotFound/index.tsx
@@ -2,6 +2,7 @@
 import type { FC } from 'react';
 import React from 'react';
 import Layout from '@theme/Layout';
+import Head from '@docusaurus/Head';
 import { translate } from '@docusaurus/Translate';
 import Link from '@docusaurus/Link';
 import style from './styles.module.scss';
@@ -14,6 +15,9 @@ const NotFound: FC = () => (
       message: 'Page Not Found',
     })}
   >
+    <Head>
+      <meta name="robots" content="noindex,follow" />
+    </Head>
     <main className={style.container}>
       <section>
         <Fitty tagName="h1" contentEditable>404</Fitty>
@@ -31,12 +35,16 @@ const NotFound: FC = () => (
         .
       </p>
       <p>
-        You can also return to
+        You can also open the
         {' '}
-        <Link href="/">
-          the home page
-        </Link>
-        . Or, return to
+        <Link to="/">home page</Link>
+        ,
+        {' '}
+        <Link to="/docs/">documentation</Link>
+        ,
+        {' '}
+        <Link to="/blog/">blog</Link>
+        , or
         {' '}
         <a
           role="button"
@@ -45,7 +53,7 @@ const NotFound: FC = () => (
             window?.history.back();
           }}
         >
-          the source page
+          return to the source page
         </a>
         .
       </p>
diff --git a/website/static/robots.txt b/website/static/robots.txt
index 2f71ab386d7..bb355ad7d64 100644
--- a/website/static/robots.txt
+++ b/website/static/robots.txt
@@ -18,6 +18,7 @@ Disallow: /docs/apisix/3.12/
 Disallow: /docs/apisix/3.13/
 Disallow: /docs/apisix/3.14/
 Disallow: /docs/apisix/3.15/
+Disallow: /docs/apisix/3.16/
 Disallow: /docs/apisix/next/
 Disallow: /docs/ingress-controller/3.10/
 Disallow: /docs/ingress-controller/3.11/
@@ -25,6 +26,7 @@ Disallow: /docs/ingress-controller/3.12/
 Disallow: /docs/ingress-controller/3.13/
 Disallow: /docs/ingress-controller/3.14/
 Disallow: /docs/ingress-controller/3.15/
+Disallow: /docs/ingress-controller/3.16/
 Disallow: /docs/ingress-controller/next/
 Disallow: /docs/helm-chart/3.10/
 Disallow: /docs/helm-chart/3.11/
@@ -32,6 +34,7 @@ Disallow: /docs/helm-chart/3.12/
 Disallow: /docs/helm-chart/3.13/
 Disallow: /docs/helm-chart/3.14/
 Disallow: /docs/helm-chart/3.15/
+Disallow: /docs/helm-chart/3.16/
 Disallow: /docs/helm-chart/next/
 Disallow: /docs/docker/3.10/
 Disallow: /docs/docker/3.11/
@@ -39,6 +42,7 @@ Disallow: /docs/docker/3.12/
 Disallow: /docs/docker/3.13/
 Disallow: /docs/docker/3.14/
 Disallow: /docs/docker/3.15/
+Disallow: /docs/docker/3.16/
 Disallow: /docs/docker/next/
 Disallow: /docs/java-plugin-runner/3.10/
 Disallow: /docs/java-plugin-runner/3.11/
@@ -46,6 +50,7 @@ Disallow: /docs/java-plugin-runner/3.12/
 Disallow: /docs/java-plugin-runner/3.13/
 Disallow: /docs/java-plugin-runner/3.14/
 Disallow: /docs/java-plugin-runner/3.15/
+Disallow: /docs/java-plugin-runner/3.16/
 Disallow: /docs/java-plugin-runner/next/
 Disallow: /docs/go-plugin-runner/3.10/
 Disallow: /docs/go-plugin-runner/3.11/
@@ -53,6 +58,7 @@ Disallow: /docs/go-plugin-runner/3.12/
 Disallow: /docs/go-plugin-runner/3.13/
 Disallow: /docs/go-plugin-runner/3.14/
 Disallow: /docs/go-plugin-runner/3.15/
+Disallow: /docs/go-plugin-runner/3.16/
 Disallow: /docs/go-plugin-runner/next/
 Disallow: /docs/python-plugin-runner/3.10/
 Disallow: /docs/python-plugin-runner/3.11/
@@ -60,6 +66,7 @@ Disallow: /docs/python-plugin-runner/3.12/
 Disallow: /docs/python-plugin-runner/3.13/
 Disallow: /docs/python-plugin-runner/3.14/
 Disallow: /docs/python-plugin-runner/3.15/
+Disallow: /docs/python-plugin-runner/3.16/
 Disallow: /docs/python-plugin-runner/next/
 
 # Chinese equivalents
@@ -69,6 +76,7 @@ Disallow: /zh/docs/apisix/3.12/
 Disallow: /zh/docs/apisix/3.13/
 Disallow: /zh/docs/apisix/3.14/
 Disallow: /zh/docs/apisix/3.15/
+Disallow: /zh/docs/apisix/3.16/
 Disallow: /zh/docs/apisix/next/
 Disallow: /zh/docs/ingress-controller/3.10/
 Disallow: /zh/docs/ingress-controller/3.11/
@@ -76,6 +84,7 @@ Disallow: /zh/docs/ingress-controller/3.12/
 Disallow: /zh/docs/ingress-controller/3.13/
 Disallow: /zh/docs/ingress-controller/3.14/
 Disallow: /zh/docs/ingress-controller/3.15/
+Disallow: /zh/docs/ingress-controller/3.16/
 Disallow: /zh/docs/ingress-controller/next/
 Disallow: /zh/docs/helm-chart/3.10/
 Disallow: /zh/docs/helm-chart/3.11/
@@ -83,6 +92,7 @@ Disallow: /zh/docs/helm-chart/3.12/
 Disallow: /zh/docs/helm-chart/3.13/
 Disallow: /zh/docs/helm-chart/3.14/
 Disallow: /zh/docs/helm-chart/3.15/
+Disallow: /zh/docs/helm-chart/3.16/
 Disallow: /zh/docs/helm-chart/next/
 Disallow: /zh/docs/docker/3.10/
 Disallow: /zh/docs/docker/3.11/
@@ -90,6 +100,7 @@ Disallow: /zh/docs/docker/3.12/
 Disallow: /zh/docs/docker/3.13/
 Disallow: /zh/docs/docker/3.14/
 Disallow: /zh/docs/docker/3.15/
+Disallow: /zh/docs/docker/3.16/
 Disallow: /zh/docs/docker/next/
 Disallow: /zh/docs/java-plugin-runner/3.10/
 Disallow: /zh/docs/java-plugin-runner/3.11/
@@ -97,6 +108,7 @@ Disallow: /zh/docs/java-plugin-runner/3.12/
 Disallow: /zh/docs/java-plugin-runner/3.13/
 Disallow: /zh/docs/java-plugin-runner/3.14/
 Disallow: /zh/docs/java-plugin-runner/3.15/
+Disallow: /zh/docs/java-plugin-runner/3.16/
 Disallow: /zh/docs/java-plugin-runner/next/
 Disallow: /zh/docs/go-plugin-runner/3.10/
 Disallow: /zh/docs/go-plugin-runner/3.11/
@@ -104,6 +116,7 @@ Disallow: /zh/docs/go-plugin-runner/3.12/
 Disallow: /zh/docs/go-plugin-runner/3.13/
 Disallow: /zh/docs/go-plugin-runner/3.14/
 Disallow: /zh/docs/go-plugin-runner/3.15/
+Disallow: /zh/docs/go-plugin-runner/3.16/
 Disallow: /zh/docs/go-plugin-runner/next/
 Disallow: /zh/docs/python-plugin-runner/3.10/
 Disallow: /zh/docs/python-plugin-runner/3.11/
@@ -111,6 +124,7 @@ Disallow: /zh/docs/python-plugin-runner/3.12/
 Disallow: /zh/docs/python-plugin-runner/3.13/
 Disallow: /zh/docs/python-plugin-runner/3.14/
 Disallow: /zh/docs/python-plugin-runner/3.15/
+Disallow: /zh/docs/python-plugin-runner/3.16/
 Disallow: /zh/docs/python-plugin-runner/next/
 
 Sitemap: https://apisix.apache.org/sitemap.xml

Reply via email to