diff --git a/docs/my-website/blog/anthropic_opus_4_5_and_advanced_features/index.md b/docs/my-website/blog/anthropic_opus_4_5_and_advanced_features/index.md index 7015918e92..8a54426dfb 100644 --- a/docs/my-website/blog/anthropic_opus_4_5_and_advanced_features/index.md +++ b/docs/my-website/blog/anthropic_opus_4_5_and_advanced_features/index.md @@ -15,6 +15,7 @@ authors: title: "CTO, LiteLLM" url: https://www.linkedin.com/in/reffajnaahsi/ image_url: https://pbs.twimg.com/profile_images/1613813310264340481/lz54oEiB_400x400.jpg +description: "Guide to Claude Opus 4.5 and advanced features in LiteLLM: Tool Search, Programmatic Tool Calling, and Effort Parameter." tags: [anthropic, claude, tool search, programmatic tool calling, effort, advanced features] hide_table_of_contents: false --- diff --git a/docs/my-website/blog/gemini_3/index.md b/docs/my-website/blog/gemini_3/index.md index 26dbc2d02b..7263acc12c 100644 --- a/docs/my-website/blog/gemini_3/index.md +++ b/docs/my-website/blog/gemini_3/index.md @@ -15,6 +15,7 @@ authors: title: "CTO, LiteLLM" url: https://www.linkedin.com/in/reffajnaahsi/ image_url: https://pbs.twimg.com/profile_images/1613813310264340481/lz54oEiB_400x400.jpg +description: "Common questions and best practices for using gemini-3-pro-preview with LiteLLM Proxy and SDK." tags: [gemini, day 0 support, llms] hide_table_of_contents: false --- diff --git a/docs/my-website/blog/gemini_3_flash/index.md b/docs/my-website/blog/gemini_3_flash/index.md index 6cb8ddad99..830c21e5f6 100644 --- a/docs/my-website/blog/gemini_3_flash/index.md +++ b/docs/my-website/blog/gemini_3_flash/index.md @@ -15,6 +15,7 @@ authors: title: "CTO, LiteLLM" url: https://www.linkedin.com/in/reffajnaahsi/ image_url: https://pbs.twimg.com/profile_images/1613813310264340481/lz54oEiB_400x400.jpg +description: "Guide to using Gemini 3 Flash on LiteLLM Proxy and SDK with day 0 support." tags: [gemini, day 0 support, llms] hide_table_of_contents: false --- diff --git a/docs/my-website/src/theme/BlogListPage/index.js b/docs/my-website/src/theme/BlogListPage/index.js new file mode 100644 index 0000000000..277556a352 --- /dev/null +++ b/docs/my-website/src/theme/BlogListPage/index.js @@ -0,0 +1,123 @@ +import React from 'react'; +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'}, +}; + +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); + + return ( + +
+
+ + {featured && Latest} +
+

{title}

+ {description &&

{description}

} + {visibleTags.length > 0 && ( +
+ {visibleTags.map(tag => { + const c = getTagColor(tag.label); + return ( + {tag.label} + ); + })} +
+ )} + +
+ + ); +} + +function Pagination({metadata}) { + const {previousPage, nextPage} = metadata; + if (!previousPage && !nextPage) return null; + return ( + + ); +} + +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.

+
+ +
+ {first && ( + + )} + {rest.map(({content}) => ( + + ))} +
+ + +
+ ); +} diff --git a/docs/my-website/src/theme/BlogListPage/styles.module.css b/docs/my-website/src/theme/BlogListPage/styles.module.css new file mode 100644 index 0000000000..747c9846a2 --- /dev/null +++ b/docs/my-website/src/theme/BlogListPage/styles.module.css @@ -0,0 +1,163 @@ +.hero { + max-width: 960px; + margin: 0 auto; + padding: 3rem 1.5rem 1rem; + text-align: center; +} + +.heroTitle { + font-size: 2.25rem; + font-weight: 700; + margin-bottom: 0.25rem; + letter-spacing: -0.02em; +} + +.heroSubtitle { + color: var(--ifm-color-emphasis-600); + font-size: 1.1rem; + margin-bottom: 0; +} + +.grid { + max-width: 960px; + margin: 0 auto; + padding: 1.5rem; + display: grid; + gap: 1rem; +} + +.cardLink { + display: block; + text-decoration: none; + color: inherit; +} + +.card { + position: relative; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 12px; + padding: 1.5rem; + padding-right: 2.5rem; + height: 100%; + transition: border-color 0.15s, transform 0.15s, background 0.15s; + background: var(--ifm-background-surface-color, var(--ifm-background-color)); +} + +.card:hover { + border-color: var(--ifm-color-primary); + transform: translateY(-2px); + background: var(--ifm-color-emphasis-100); +} + +.cardFeatured { + composes: card; + border-color: var(--ifm-color-primary-lighter); + background: var(--ifm-color-emphasis-100); +} + +.meta { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 0.5rem; +} + +.time { + font-size: 0.8rem; + font-weight: 500; + color: var(--ifm-color-emphasis-600); + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.badge { + font-size: 0.65rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.06em; + padding: 2px 8px; + border-radius: 99px; + background: var(--ifm-color-primary); + color: #fff; +} + +.title { + font-size: 1.15rem; + font-weight: 600; + margin: 0 0 0.4rem; + line-height: 1.35; +} + +.desc { + font-size: 0.88rem; + color: var(--ifm-color-emphasis-700); + line-height: 1.5; + margin: 0 0 0.75rem; +} + +.tags { + display: flex; + gap: 6px; + flex-wrap: wrap; +} + +.tag { + font-size: 0.7rem; + font-weight: 500; + padding: 2px 10px; + border-radius: 99px; + background: var(--tag-bg); + color: var(--tag-text); +} + +:global([data-theme='dark']) .tag { + background: var(--tag-bg-dark); + color: var(--tag-text-dark); +} + +.arrow { + position: absolute; + right: 1rem; + top: 50%; + transform: translateY(-50%); + color: var(--ifm-color-emphasis-400); + transition: color 0.15s, transform 0.15s; +} + +.card:hover .arrow { + color: var(--ifm-color-primary); + transform: translateY(-50%) translateX(3px); +} + +.pagination { + max-width: 960px; + margin: 0 auto; + padding: 1rem 1.5rem 3rem; + display: flex; + justify-content: space-between; +} + +.paginationLink { + font-size: 0.9rem; + font-weight: 500; + color: var(--ifm-color-primary); + text-decoration: none; +} + +.paginationLink:hover { + text-decoration: underline; +} + +@media (min-width: 640px) { + .grid { + grid-template-columns: repeat(2, 1fr); + } + + .grid .cardLink:first-child { + grid-column: 1 / -1; + } + + .grid .cardLink:last-child:nth-child(even) { + grid-column: 1 / -1; + } +}