This is an automated email from the ASF dual-hosted git repository.
moonming pushed a commit to branch feat/seo-homepage-rewrite
in repository https://gitbox.apache.org/repos/asf/apisix-website.git
The following commit(s) were added to refs/heads/feat/seo-homepage-rewrite by
this push:
new d52ce902617 feat(seo): add /comparisons/ hub page; point navbar there
d52ce902617 is described below
commit d52ce902617b7bb1397a26795b90d5a15ed5473d
Author: Ming Wen <[email protected]>
AuthorDate: Mon Jun 22 17:43:24 2026 +0800
feat(seo): add /comparisons/ hub page; point navbar there
The navbar Comparisons link pointed at /learning-center/tags/comparison, the
default Docusaurus tag feed (full article bodies stacked — looked
unpolished).
Replace with a dedicated, on-brand /comparisons/ hub: a card grid linking to
each comparison article, with CollectionPage/ItemList structured data.
---
config/navbar.js | 2 +-
website/src/css/comparisons.scss | 99 +++++++++++++++++++++++++++++++++++
website/src/pages/comparisons.tsx | 107 ++++++++++++++++++++++++++++++++++++++
3 files changed, 207 insertions(+), 1 deletion(-)
diff --git a/config/navbar.js b/config/navbar.js
index 10a55444ff2..382062740b1 100644
--- a/config/navbar.js
+++ b/config/navbar.js
@@ -59,7 +59,7 @@ module.exports = [
target: '_parent',
},
{
- to: '/learning-center/tags/comparison',
+ to: '/comparisons/',
label: 'Comparisons',
position: 'right',
target: '_parent',
diff --git a/website/src/css/comparisons.scss b/website/src/css/comparisons.scss
new file mode 100644
index 00000000000..0c8c20e535f
--- /dev/null
+++ b/website/src/css/comparisons.scss
@@ -0,0 +1,99 @@
+.comparisons {
+ max-width: 1000px;
+ margin: 0 auto;
+ padding: clamp(3rem, 6vw, 5rem) var(--ifm-spacing-horizontal) 4rem;
+}
+
+.comparisons__header {
+ text-align: center;
+ margin-bottom: 2.5rem;
+}
+
+.comparisons__eyebrow {
+ display: inline-block;
+ font-size: 0.82rem;
+ font-weight: 600;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+ color: #a32d2d;
+ background: #fcebeb;
+ padding: 5px 14px;
+ border-radius: 20px;
+ margin-bottom: 1rem;
+}
+
+.comparisons__title {
+ font-size: clamp(2rem, 1rem + 3vw, 2.75rem);
+ font-weight: 700;
+ margin-bottom: 0.6rem;
+}
+
+.comparisons__subtitle {
+ color: var(--ifm-color-emphasis-700);
+ max-width: 640px;
+ margin: 0 auto;
+ font-size: 1.05rem;
+ line-height: 1.6;
+}
+
+.comparisons__grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1.25rem;
+}
+
+@media (max-width: 768px) {
+ .comparisons__grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+.comparisons__card {
+ display: flex;
+ flex-direction: column;
+ background: var(--ifm-background-surface-color);
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-top: 3px solid #e8433e;
+ border-radius: 12px;
+ padding: 1.6rem 1.5rem;
+ color: inherit;
+ transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s
ease;
+
+ &:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 10px 28px rgb(0 0 0 / 8%);
+ color: inherit;
+ text-decoration: none;
+ }
+
+ &:hover .comparisons__card-title {
+ color: #e8433e;
+ }
+}
+
+.comparisons__card-title {
+ font-size: 1.2rem;
+ font-weight: 700;
+ line-height: 1.3;
+ margin: 0 0 0.5rem;
+}
+
+.comparisons__card-desc {
+ font-size: 0.95rem;
+ line-height: 1.55;
+ color: var(--ifm-color-emphasis-700);
+ margin: 0 0 1rem;
+ flex: 1;
+}
+
+.comparisons__card-cta {
+ font-size: 0.95rem;
+ font-weight: 600;
+ color: #e8433e;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .comparisons__card:hover {
+ transform: none;
+ }
+}
diff --git a/website/src/pages/comparisons.tsx
b/website/src/pages/comparisons.tsx
new file mode 100644
index 00000000000..c5834754ac6
--- /dev/null
+++ b/website/src/pages/comparisons.tsx
@@ -0,0 +1,107 @@
+import type { FC } from 'react';
+import React from 'react';
+import Layout from '@theme/Layout';
+import Head from '@docusaurus/Head';
+import Link from '@docusaurus/Link';
+import Translate, { translate } from '@docusaurus/Translate';
+
+import '../css/comparisons.scss';
+
+interface Comparison {
+ title: string;
+ description: string;
+ to: string;
+}
+
+const COMPARISONS: Comparison[] = [
+ {
+ title: 'Apache APISIX vs Kong',
+ description:
+ 'Architecture, performance benchmarks, plugin ecosystem, Kubernetes
support, and when to choose each.',
+ to: '/learning-center/apisix-vs-kong/',
+ },
+ {
+ title: 'Open-source API gateways compared',
+ description:
+ 'APISIX vs Kong vs Envoy vs Traefik — a feature-by-feature look at the
leading open-source gateways.',
+ to: '/learning-center/open-source-api-gateway-comparison/',
+ },
+ {
+ title: 'API gateway vs load balancer',
+ description:
+ 'How an API gateway and a load balancer differ, where they overlap, and
when to use each.',
+ to: '/learning-center/api-gateway-vs-load-balancer/',
+ },
+ {
+ title: 'Kubernetes API gateway',
+ description:
+ 'Gateway API vs Ingress, ingress controllers, and deploying an API
gateway on Kubernetes.',
+ to: '/learning-center/kubernetes-api-gateway/',
+ },
+];
+
+const COLLECTION_SCHEMA = {
+ '@context': 'https://schema.org',
+ '@type': 'CollectionPage',
+ name: 'Apache APISIX API gateway comparisons',
+ url: 'https://apisix.apache.org/comparisons/',
+ mainEntity: {
+ '@type': 'ItemList',
+ itemListElement: COMPARISONS.map((c, index) => ({
+ '@type': 'ListItem',
+ position: index + 1,
+ name: c.title,
+ url: `https://apisix.apache.org${c.to}`,
+ })),
+ },
+};
+
+const Comparisons: FC = () => (
+ <Layout>
+ <Head>
+ <title>
+ {translate({ id: 'comparisons.meta.title', message: 'API Gateway
Comparisons | Apache APISIX' })}
+ </title>
+ <meta
+ name="description"
+ content={translate({
+ id: 'comparisons.meta.description',
+ message:
+ 'Compare Apache APISIX with Kong, Envoy, Traefik and other API
gateways — architecture, performance, and features.',
+ })}
+ />
+ <link rel="canonical" href="https://apisix.apache.org/comparisons/" />
+ <script
type="application/ld+json">{JSON.stringify(COLLECTION_SCHEMA)}</script>
+ </Head>
+ <div className="comparisons">
+ <header className="comparisons__header">
+ <span className="comparisons__eyebrow">
+ <Translate id="comparisons.eyebrow">Comparisons</Translate>
+ </span>
+ <h1 className="comparisons__title">
+ <Translate id="comparisons.title">Compare Apache APISIX</Translate>
+ </h1>
+ <p className="comparisons__subtitle">
+ <Translate id="comparisons.subtitle">
+ See how Apache APISIX stacks up against other API gateways and
architectures — and pick
+ the right tool for your stack.
+ </Translate>
+ </p>
+ </header>
+ <div className="comparisons__grid">
+ {COMPARISONS.map((comparison) => (
+ <Link className="comparisons__card" to={comparison.to}
key={comparison.to}>
+ <h2 className="comparisons__card-title">{comparison.title}</h2>
+ <p className="comparisons__card-desc">{comparison.description}</p>
+ <span className="comparisons__card-cta">
+ <Translate id="comparisons.card.cta">Read comparison</Translate>
+ {' →'}
+ </span>
+ </Link>
+ ))}
+ </div>
+ </div>
+ </Layout>
+);
+
+export default Comparisons;