Skip to content

Commit d0bda58

Browse files
authored
feat: add ai-gateway page (#1896)
1 parent 09bb3de commit d0bda58

22 files changed

+2301
-20
lines changed

blog/en/docusaurus.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ module.exports = {
8181
backgroundColor: '#e8433e',
8282
textColor: 'white',
8383
content:
84-
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="https://apisix.apache.org/blog/2025/04/08/introducing-apisix-ai-gateway/"> Learn More</a>',
84+
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="/ai-gateway/"> Learn More</a>',
8585
},
8686
prism: {
8787
theme: require('prism-react-renderer/themes/github'),

blog/zh/docusaurus.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ module.exports = {
8383
backgroundColor: '#e8433e',
8484
textColor: 'white',
8585
content:
86-
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="https://apisix.apache.org/blog/2025/04/08/introducing-apisix-ai-gateway/"> Learn More</a>',
86+
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="/ai-gateway/"> Learn More</a>',
8787
},
8888
prism: {
8989
theme: require('prism-react-renderer/themes/github'),

doc/docusaurus.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ module.exports = {
237237
backgroundColor: '#e8433e',
238238
textColor: 'white',
239239
content:
240-
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="https://apisix.apache.org/blog/2025/04/08/introducing-apisix-ai-gateway/"> Learn More</a>',
240+
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="/ai-gateway/"> Learn More</a>',
241241
},
242242
prism: {
243243
theme: require('prism-react-renderer/themes/github'),

website/docusaurus.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ module.exports = {
112112
backgroundColor: '#e8433e',
113113
textColor: 'white',
114114
content:
115-
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="https://apisix.apache.org/blog/2025/04/08/introducing-apisix-ai-gateway/"> Learn More</a>',
115+
'\u{1F914} Introducing APISIX AI Gateway – Built for LLMs and AI workloads. <a target="_blank" rel="noopener noreferrer" href="/ai-gateway/"> Learn More</a>',
116116
},
117117
prism: {
118118
theme: require('prism-react-renderer/themes/github'),

website/package.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@docusaurus/module-type-aliases": "^2.0.0-beta.6",
1919
"@svgr/webpack": "^5.5.0",
2020
"@tsconfig/docusaurus": "^1.0.4",
21-
"@types/react": "^17.0.20",
21+
"@types/react": "^18.0.20",
2222
"@types/react-helmet": "^6.1.2",
2323
"@types/react-lazy-load-image-component": "^1.5.2",
2424
"@types/react-router-dom": "^5.1.8",
@@ -29,24 +29,31 @@
2929
"typescript": "^4.4.2"
3030
},
3131
"dependencies": {
32+
"@chakra-ui/icons": "2.0.17",
33+
"@chakra-ui/pro-theme": "^0.0.64",
34+
"@chakra-ui/react": "2.5.1",
3235
"@docusaurus/core": "2.0.0-beta.6",
3336
"@docusaurus/logger": "^2.0.0-rc.1",
3437
"@docusaurus/preset-classic": "2.0.0-beta.6",
38+
"@emotion/react": "^11.10.5",
39+
"@emotion/styled": "^11.10.5",
3540
"@iconify/icons-akar-icons": "^1.2.8",
3641
"@iconify/react": "^3.2.2",
3742
"@use-gesture/react": "^10.2.16",
3843
"change-case": "^4.1.2",
3944
"clsx": "^1.1.1",
4045
"docusaurus-plugin-sass": "^0.2.2",
4146
"fitty": "^2.3.6",
47+
"framer-motion": "^12.4.1",
4248
"gsap": "^3.7.1",
4349
"lethargy": "^1.0.9",
4450
"patch-package": "^6.4.7",
4551
"postinstall-postinstall": "^2.1.0",
4652
"raw-loader": "^4.0.2",
4753
"rc-image": "^5.6.2",
48-
"react": "^17.0.2",
49-
"react-dom": "^17.0.2",
54+
"react": "^18.2.0",
55+
"react-dom": "^18.2.0",
56+
"react-icons": "^5.5.0",
5057
"react-lazy-load-image-component": "^1.5.4",
5158
"react-spring": "^9.4.5",
5259
"react-transition-group": "^4.4.1",
@@ -55,6 +62,7 @@
5562
"remark-mdx": "^1.6.22",
5663
"sass": "^1.53.0",
5764
"styled-components": "^5.3.3",
65+
"swiper": "^11.2.6",
5866
"three": "^0.131.3",
5967
"unist-util-visit": "^2.0.2",
6068
"video.js": "^7.19.2"
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import React from 'react';
2+
import {
3+
Box,
4+
Container,
5+
Heading,
6+
Stack,
7+
Text,
8+
Grid,
9+
GridItem,
10+
Button,
11+
Icon,
12+
} from '@chakra-ui/react';
13+
import { motion } from 'framer-motion';
14+
import { useAdvantages } from './data';
15+
16+
import AvifImage from './AvifImage';
17+
18+
const Advantage: React.FC = () => {
19+
const advantages = useAdvantages();
20+
21+
return (
22+
<Box bg="#f9f9fb">
23+
<Container py={{ base: '72px', lg: '120px' }}>
24+
<Box textAlign="center" mb={{ base: '48px', lg: '80px' }}>
25+
<Heading
26+
as="h2"
27+
variant="h2"
28+
>
29+
Transform APISIX into an AI Gateway with AI Plugins
30+
</Heading>
31+
<Button
32+
as="a"
33+
href="https://apisix.apache.org/docs/apisix/next/plugins/ai-proxy/"
34+
target="_blank"
35+
w={{ base: '158px', lg: 'auto' }}
36+
h={{ base: '46px', lg: '48px' }}
37+
variant="gradient"
38+
mt="8"
39+
>
40+
Read the Docs
41+
</Button>
42+
</Box>
43+
<Grid
44+
as={motion.div as any}
45+
templateRows={{
46+
base: 'repeat(1, 1fr 0.5fr)',
47+
lg: 'repeat(1, 1fr 0.5fr)',
48+
} as const}
49+
templateColumns={{ base: 'repeat(2, 1fr)', lg: 'repeat(4, 1fr)' }}
50+
gap={6}
51+
>
52+
{/* the first three list */}
53+
{advantages.slice(0, 3).map((item, index) => (
54+
<GridItem
55+
gridArea={{ base: item.mobileArea, lg: item.gridArea }}
56+
as={motion.div as any}
57+
key={item.title as string}
58+
initial={{ y: 20, opacity: 0 }}
59+
whileInView={{
60+
y: 0,
61+
opacity: 1,
62+
transition: { delay: 0.2 + 0.1 * index },
63+
}}
64+
viewport={{ once: true }}
65+
bg="#ffffff"
66+
borderRadius="8px"
67+
display={{ base: 'flex', lg: 'unset' }}
68+
alignItems={{ base: 'center' }}
69+
justifyContent="center"
70+
>
71+
<Stack
72+
spacing="4"
73+
px={{ base: '4', lg: '8' }}
74+
py="10"
75+
alignItems="center"
76+
textAlign="center"
77+
>
78+
{item.icon && (
79+
<Box
80+
w="48px"
81+
h="48px"
82+
p="1px"
83+
background="linear-gradient(to right, #8F41E9, #578AEF)"
84+
borderRadius="8px"
85+
>
86+
<Box
87+
background="#fff"
88+
borderRadius="8px"
89+
height="100%"
90+
display="flex"
91+
justifyContent="center"
92+
alignItems="center"
93+
>
94+
<Icon as={item.icon as any} boxSize="28px" color="brand.500" />
95+
</Box>
96+
</Box>
97+
)}
98+
<Heading
99+
as="h4"
100+
variant="h4"
101+
fontSize={{ base: '26px', lg: '28px' }}
102+
bg="var(--chakra-colors-gradient-600)"
103+
bgClip="text"
104+
{...item.titleStyle}
105+
>
106+
{item.title}
107+
</Heading>
108+
<Text
109+
fontSize={{ base: '16px', lg: '18px' }}
110+
color="#656b8a"
111+
letterSpacing="-0.2px"
112+
>
113+
{item.description}
114+
</Text>
115+
</Stack>
116+
</GridItem>
117+
))}
118+
{/* the last list */}
119+
{advantages.slice(3, 4).map((item) => (
120+
<GridItem
121+
gridArea={{ base: item.mobileArea, lg: item.gridArea }}
122+
as={motion.div as any}
123+
key={item.title as string}
124+
initial={{ y: 20, opacity: 0 }}
125+
whileInView={{
126+
y: 0,
127+
opacity: 1,
128+
transition: { delay: 0.6 },
129+
}}
130+
viewport={{ once: true }}
131+
bg="#ffffff"
132+
borderRadius="8px"
133+
>
134+
<Stack
135+
spacing="6"
136+
px={{ base: '6', lg: '12' }}
137+
py="10"
138+
alignItems="left"
139+
textAlign={{ base: 'left', lg: 'left' }}
140+
>
141+
<Heading
142+
as="h4"
143+
variant="h4"
144+
fontSize={{ base: '26px', lg: '32px' }}
145+
{...item.titleStyle}
146+
>
147+
{item.title}
148+
</Heading>
149+
<Box>
150+
<Text
151+
fontSize={{ base: '16px', lg: '19px' }}
152+
lineHeight="1.6"
153+
color="#656b8a"
154+
>
155+
{item.description}
156+
</Text>
157+
<AvifImage
158+
src={item.picture}
159+
alt=""
160+
height="50px"
161+
w="full"
162+
objectFit="contain"
163+
transform={{ base: 'scale(1.03)', lg: 'scale(1.12)' }}
164+
mt={{ base: '30px', lg: '50px' }}
165+
/>
166+
</Box>
167+
</Stack>
168+
</GridItem>
169+
))}
170+
</Grid>
171+
172+
<Box
173+
as={motion.div}
174+
initial={{ y: 20, opacity: 0 }}
175+
whileInView={{ y: 0, opacity: 1, transition: { delay: 0.7 } }}
176+
viewport={{ once: true }}
177+
mt={{ base: '60px', lg: '80px' }}
178+
>
179+
<Box
180+
position="relative"
181+
width="100%"
182+
height={{ base: 'auto', md: '600px', lg: '810px' }}
183+
display={{ base: 'none', md: 'inherit' }}
184+
>
185+
<AvifImage
186+
src="https://static.api7.ai/uploads/2025/04/17/OzCNXRTl_apisix-ai-gateway-architecture.png"
187+
alt="AI Gateway Architecture"
188+
objectFit="cover"
189+
width="100%"
190+
height="100%"
191+
/>
192+
</Box>
193+
194+
{/* Mobile */}
195+
<Box maxW="full" mx="auto" display={{ base: 'unset', md: 'none' }}>
196+
<AvifImage
197+
src="https://static.api7.ai/uploads/2025/04/17/ykJ74KyV_apisix-ai-gateway-mobile.png"
198+
alt="AI Gateway Architecture"
199+
objectFit="cover"
200+
width="100%"
201+
height="100%"
202+
/>
203+
</Box>
204+
</Box>
205+
</Container>
206+
</Box>
207+
);
208+
};
209+
210+
export default Advantage;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import type { ImageProps } from '@chakra-ui/react';
3+
import { Image } from '@chakra-ui/react';
4+
5+
const AvifImage: React.FC<ImageProps> = ({ src, alt, ...props }) => {
6+
if (src?.toLowerCase().includes('.svg') || src?.includes('imageMogr2/')) {
7+
return <Image src={src} alt={alt} {...props} />;
8+
}
9+
10+
return (
11+
<picture>
12+
<source srcSet={`${src}?imageMogr2/format/avif`} type="image/avif" />
13+
<source srcSet={`${src}?imageMogr2/format/webp`} type="image/webp" />
14+
<Image src={src} alt={alt} {...props} />
15+
</picture>
16+
);
17+
};
18+
19+
export default AvifImage;

0 commit comments

Comments
 (0)