From 85cb7db8b9ebd832aee25be54a3ace478d36045b Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Sat, 11 Apr 2026 18:02:48 -0700 Subject: [PATCH] blog list page: Ramp-style flat list with hero, provider marquee, hiring CTA --- .../src/theme/BlogListPage/index.js | 192 ++++++++++-------- 1 file changed, 103 insertions(+), 89 deletions(-) diff --git a/docs/my-website/src/theme/BlogListPage/index.js b/docs/my-website/src/theme/BlogListPage/index.js index 277556a3528..9c1844c7f7e 100644 --- a/docs/my-website/src/theme/BlogListPage/index.js +++ b/docs/my-website/src/theme/BlogListPage/index.js @@ -3,78 +3,86 @@ import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; import styles from './styles.module.css'; -const TAG_COLORS = { - gemini: {bg: '#d2e3fc', text: '#174ea6', darkBg: '#1a3a5c', darkText: '#8ab4f8'}, - anthropic: {bg: '#fde0c4', text: '#b33d00', darkBg: '#4a2800', darkText: '#ffb74d'}, - claude: {bg: '#fde0c4', text: '#b33d00', darkBg: '#4a2800', darkText: '#ffb74d'}, - llms: {bg: '#c8e6c9', text: '#1b5e20', darkBg: '#1b3d1f', darkText: '#81c784'}, -}; +// ── Provider marquee ────────────────────────────────────────────────────── +const PROVIDERS = [ + { name: 'OpenAI', img: 'https://www.google.com/s2/favicons?domain=openai.com&sz=64' }, + { name: 'Anthropic', img: 'https://www.google.com/s2/favicons?domain=claude.ai&sz=64' }, + { name: 'Google Gemini', img: 'https://www.google.com/s2/favicons?domain=ai.google.dev&sz=64' }, + { name: 'AWS Bedrock', img: 'https://www.google.com/s2/favicons?domain=aws.amazon.com&sz=64' }, + { name: 'Azure OpenAI', img: 'https://www.google.com/s2/favicons?domain=azure.microsoft.com&sz=64' }, + { name: 'Mistral AI', img: 'https://www.google.com/s2/favicons?domain=mistral.ai&sz=64' }, + { name: 'Meta Llama', img: 'https://www.google.com/s2/favicons?domain=meta.com&sz=64' }, + { name: 'Groq', img: 'https://www.google.com/s2/favicons?domain=groq.com&sz=64' }, + { name: 'Hugging Face', img: 'https://www.google.com/s2/favicons?domain=huggingface.co&sz=64' }, + { name: 'Perplexity', img: 'https://www.google.com/s2/favicons?domain=perplexity.ai&sz=64' }, + { name: 'DeepSeek', img: 'https://www.google.com/s2/favicons?domain=deepseek.com&sz=64' }, + { name: 'Cohere', img: 'https://www.google.com/s2/favicons?domain=cohere.com&sz=64' }, + { name: 'Together AI', img: 'https://www.google.com/s2/favicons?domain=together.ai&sz=64' }, + { name: 'Vertex AI', img: 'https://www.google.com/s2/favicons?domain=cloud.google.com&sz=64' }, +]; -function hashHue(str) { - let hash = 0; - for (let i = 0; i < str.length; i++) { - hash = str.charCodeAt(i) + ((hash << 5) - hash); - } - return Math.abs(hash) % 360; -} - -function getTagColor(label) { - const key = label.toLowerCase(); - for (const [k, v] of Object.entries(TAG_COLORS)) { - if (key === k) return v; - } - const hue = hashHue(key); - return { - bg: `hsl(${hue}, 40%, 90%)`, - text: `hsl(${hue}, 60%, 25%)`, - darkBg: `hsl(${hue}, 40%, 20%)`, - darkText: `hsl(${hue}, 50%, 75%)`, - }; -} - -function formatDate(dateStr) { - const d = new Date(dateStr); - const now = new Date(); - const diffDays = Math.floor((now - d) / (1000 * 60 * 60 * 24)); - if (diffDays <= 0) return 'Today'; - if (diffDays === 1) return '1d ago'; - if (diffDays < 30) return `${diffDays}d ago`; - return d.toLocaleDateString('en-US', {month: 'short', day: 'numeric', year: 'numeric'}); -} - -function BlogCard({post, featured}) { - const {title, permalink, date, description, tags} = post; - const visibleTags = (tags || []).slice(0, 3); +const DOUBLED = [...PROVIDERS, ...PROVIDERS]; +function ProviderMarquee() { return ( - -
-
- - {featured && Latest} +
+

Routing to 100+ providers

+
+
+
+
+ {DOUBLED.map((p, i) => ( + + {p.name} + {p.name} + | + + ))}
+
+
+ ); +} + +// ── Post row ────────────────────────────────────────────────────────────── +function formatDate(dateStr) { + return new Date(dateStr).toLocaleDateString('en-US', { + month: 'long', day: 'numeric', year: 'numeric', + }); +} + +function AuthorList({authors}) { + if (!authors || authors.length === 0) return null; + return ( + <> + {authors.map((a, i) => ( + + {i > 0 && } + {a.url ? ( + {a.name} + ) : ( + {a.name} + )} + + ))} + + ); +} + +function PostRow({post}) { + const {title, permalink, date, description, authors} = post; + return ( +
+

{title}

- {description &&

{description}

} - {visibleTags.length > 0 && ( -
- {visibleTags.map(tag => { - const c = getTagColor(tag.label); - return ( - {tag.label} - ); - })} -
- )} - -
- + + {description &&

{description}

} +
+ + {authors && authors.length > 0 && — } + +
+
); } @@ -83,41 +91,47 @@ function Pagination({metadata}) { if (!previousPage && !nextPage) return null; return ( ); } +// ── Page ────────────────────────────────────────────────────────────────── export default function BlogListPage(props) { const items = props.items || []; const metadata = props.metadata || {}; - const [first, ...rest] = items; return ( -
-

The LiteLLM Blog

-

Guides, announcements, and best practices from the LiteLLM team.

-
+
+ {/* Hero */} +
+

AI Gateway

+

Engineering

+

+ How we build the world's most widely used open-source AI Gateway. + Routing, reliability, observability, and what we learn along the way. +

+ + We're hiring! + +
-
- {first && ( - - )} - {rest.map(({content}) => ( - - ))} -
+ - + {/* Post list */} +
+ {items.map(({content}) => ( + + ))} +
+ + +
); }