LiteLLM Dashboard 页面开发规范:基于 Next.js App Router 的目录结构与组件组织实践

发布时间:2026/9/8 17:53:20

LiteLLM Dashboard 页面开发规范:基于 Next.js App Router 的目录结构与组件组织实践
LiteLLM Dashboard 页面开发规范基于 Next.js App Router 的目录结构与组件组织实践【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellmLiteLLM Dashboard 是 LiteLLM 代理网关配套的管理控制台位于ui/litellm-dashboard当前正处于一次以“降低开发摩擦”为目标的架构级重构之中。本篇技术指南以 ui/litellm-dashboard/src/app/(dashboard)/README.md/README.md) 为骨架系统讲解新控制台基于 Next.js App Router 的文件驱动路由、页面级目录组织、纯展示组件、hooks 与工具函数的摆放约定并结合仓库实际代码与迁移映射帮助贡献者快速上手新增与管理一个页面。一、背景一次以“降低开发摩擦”为目标的 UI 重构文档开宗明义LiteLLM UI 正在经历重构/重写以降低开发摩擦为目标。任何新增贡献前都应当先理解这篇 README因为它定义了新控制台必须遵守的代码组织纪律。这一重构意图在代码中有明确的印证。在 UI 根路由入口/page.tsx#L44-L50) 中控制台仍会兼容旧的?page深链并自动重定向到新式 path 路由而在 迁移映射表 中可以看到一份「旧侧边栏页面 ID ↔ 新路由段」的一一对应表例如api-keys → api-keys、models → models-and-endpoints、llm-playground → playground、new_usage → usage、usage → old-usage等。该文件源码注释明确写道“新增一条记录即可把侧边栏与深链引导到新路径删除它即可回滚”——这正是新老两套路由共存期的安全迁移机制也解释了为什么本文档要求严格遵循特定文件结构。另外需要特别说明本 README 是目标态规范。仓库中仍存在大量尚未迁移、位于src/components下的“旧式”巨型组件例如ui/litellm-dashboard/src/components/Teams.tsx、TeamsPage/TeamsTable.tsx它们将被逐步拆解为文档所描述的新结构。因此新代码一律按本文档约定编写旧代码的清理与迁移可参照 迁移映射表。二、Next.js 严格文件结构路由即文件系统2.1 核心原则一个页面 一个独立文件夹文档强调项目遵循严格的 Next.js 文件结构。侧边栏决定站点有哪些页面而每个页面都收纳在自己的文件夹中路由完全由 Next.js 依据文件结构自动处理开发者无需手写任何路由表。文档给出的范例. ├── settings ├── admin-settings │ └── page.tsx当用户访问/settings/admin-settings时Next.js 会自动渲染settings/admin-settings/page.tsx。也就是说目录路径即 URL 路径page.tsx即页面入口组件。2.2 路由组Route Group用(dashboard)藏起前缀目录在真实的 App Router 目录中URL 并不总能与磁盘目录一一对应。Next.js 提供**路由组Route Group**机制目录名用圆括号包裹时该目录名不会出现在 URL 中但仍能享受layout.tsx与文件组织的全部好处。文档原文即举了(dashboard)作为示例。当前仓库中(dashboard)目录) 正是 LiteLLM AI 网关控制台全部页面的家但它不会以/dashboard形式暴露给用户——实际的页面 URL 是/api-keys、/teams、/playground这样直接以页面名开头的路径。路由组让这批页面可以共享同一个仪表盘布局 layout.tsx/layout.tsx)而不必污染 URL。2.3 仓库实测(dashboard)下的页面全景从源码目录可以直观看到这套结构当前承载的页面规模均为一页一文件夹access-groups/、agents/、api-keys/、api-reference/、budgets/、caching/cost-optimization/、cost-tracking/、guardrails/、guardrails-monitor/logging-and-alerts/、mcp-servers/、memory/、model-hub-table/models-and-endpoints/、old-usage/、usage/、organizations/playground/、policies/、projects/、prompts/、router-settings/search-tools/、skills/、tag-management/、teams/、tool-policies/transform-request/、ui-theme/、users/、vector-stores/、workflows/、admin-panel/其中每个目录都含有一个page.tsx。以极简的 teams 页面入口/teams/page.tsx) 为例页面入口通常只做“装配”工作——取出认证信息、渲染视图组件use client; import Teams from /components/Teams; import useAuthorized from /app/(dashboard)/hooks/useAuthorized; export default function TeamsPage() { const { accessToken, userId, userRole, premiumUser } useAuthorized(); return Teams accessToken{accessToken} userID{userId} userRole{userRole} premiumUser{premiumUser ?? false} /; }这里的useAuthorized也是一个从hooks目录引入的 hook恰好对应下文「hooks 独立成目录」的约定。注意page.tsx必须显式声明use client与export default组件即默认导出页面。2.4 布局层做了什么page.tsx之上还有一层layout.tsx。(dashboard)/layout.tsx/layout.tsx#L137-L155) 中的DashboardShell组装了控制台的标准外壳左侧SidebarProvider侧边栏、顶部DashboardHeader、若干告警横幅DebugWarningBanner、NoRedisWarningBanner、LicenseExpiryBanner最后将children即每个页面的渲染结果放入可滚动主区域。这就是“路由组 layout 子页面”三者协作的典型形态layout 提供骨架page 提供内容。三、页面内部的标准文件结构文档给出了一套“页面模板”强烈建议每个新页面都按此组织。原文的teams页示例├── teams │ ├── TeamsView.tsx │ ├── components │ │ ├── TeamsFilters.tsx │ │ ├── TeamsHeaderTabs.tsx │ │ ├── TeamsTable │ │ │ ├── ModelsCell.tsx │ │ │ └── TeamsTable.tsx │ │ └── modals │ │ ├── CreateTeamModal.tsx │ │ └── DeleteTeamModal.tsx │ ├── hooks │ │ └── useFetchTeams.ts │ └── page.tsx解读这套结构的层次语义目录/文件职责说明page.tsx页面入口/装配层只做数据与视图的接线尽量不写业务逻辑TeamsView.tsx页面级视图容器与page.tsx平级承接页面主要布局components/页面私有组件仅被本页使用可再分子目录modals/、TeamsTable/hooks/页面私有 hooks如useFetchTeams.ts负责拉取数据utils.ts页面私有纯函数数据处理、格式化等components/TeamsTable/ModelsCell.tsx说明组件目录还可以继续嵌套一张表格组件内再拆出“单元格组件”粒度自由但要有层级。仓库现状提醒仓库中大量已迁移页面把“页面私有组件”文件夹命名为_components/例如 admin-panel/_components/AdminPanel.tsx/admin-panel/_components/AdminPanel.tsx)、agents/_components/agents/_components)。带下划线前缀的目录同样不会被 Next.js 当作路由段属于“只被 import、不参与路由”的私有代码目录与文档示例中的components/语义一致。命名统一以文档/最新代码评审结论为准但**“私有组件只出现在页面文件夹内”的原则是硬性的**。四、组件编码纪律能“哑”则“哑”长了就拆文档对组件文件本身提出了两条硬约束这对控制台这种动辄几百行表格/表单的代码库尤其重要4.1 组件应尽量“愚蠢”dumbAll component files should ideally be as dumb as possible. Their only job should be to take the data they need from hooks or props and render them to the UI.即组件尽量不感知外部世界只做两件事——从hooks或props拿到数据把它渲染到 UI。数据获取、状态管理、鉴权等逻辑应上移到 hook 或由父级注入让组件保持可预测、可复用、易测试。仓库中测试文件与组件同目录放置正说明这种“哑组件 显式依赖注入”的设计极大方便了单测。例如 ApiKeysDashboard.test.tsx/api-keys/ApiKeysDashboard.test.tsx) 通过 mockuseKeys、useSearchParams等依赖来渲染页面page.test.tsx/page.test.tsx) 则直接渲染page.tsx验证登录/深链重定向逻辑。4.2 超过约 300 行必须拆分If a component file becomes too large (over300lines or so), please break it down into smaller components.300 行是文档给出的经验阈值。一旦组件文件逼近该规模就应该按渲染块或职责拆成更小的组件——例如表格行拆出Cell组件、弹窗拆到modals/子目录。这不只是审美问题行数直接关联单测可写性、review 成本与合并冲突概率。4.3 就近放置 最低公共祖先原则两条定位规则共同约束组件与 hooks 的“物理位置”就近放置一个组件只放在它会被使用的地方。若某个组件只被teams页用到它就属于teams/components/而不是全局组件目录。最低公共祖先lowest common ancestor当组件被多个页面共享时向上移动到“引用它的所有页面/组件共同的最低一层目录”例如从页面级components/提升到 dashboard 路由组的 components//components)当前存放SidebarProvider.tsx这类全仪表盘共享的壳组件再往上才是src/components、src/hooks等应用级公共目录。这两条规则合成一句话代码放在“离唯一使用者最近、离所有使用者最远”都不对要放在“离所有使用者足够近且最近公共点”的位置。五、Hooks纯 TypeScript 文件除非它是 Context Provider文档对 hooks 的规定非常具体All hooks should be pure.tsfiles in a dedicatedhooksfolder unless they serve as context managers.拆解为三层含义纯.ts文件hooks 不应以.tsx存在。既然是 hook逻辑就与 JSX 无关文件后缀必须为.ts。独立的hooks文件夹hooks 不散落在页面根部或组件里而是统一放进该功能/页面自己的hooks/目录。唯一的例外是 context manager如果 hook 的本质是“管理 React Context 并向树中注入 Provider/暴露useContext”才可以脱离纯.ts规则因为它确实需要渲染 Provider本质已接近组件。仓库中该约定已大面积落地。例如 页面级 hooks 目录/hooks) 之下按领域分子目录管理hooks/teams/useTeams.ts团队数据请求API 层 call 与查询 hook 同文件导出见 api-keys 中的引用/api-keys/ApiKeysDashboard.tsx)hooks/agents/useAgents.tsAgent 列表/健康度hooks/users/useUsers.ts、hooks/mcpServers/useMCPServers.ts、hooks/spendLogs/useSpendLogUsers.ts、hooks/routingGroups/useRoutingGroups.tshooks/common/useResourceList.tshooks/common/queryKeysFactory.ts抽取的通用资源列表查询与 react-query key 工厂——这正是“多个页面共享 → 上移到最近公共hooks目录”的实例。几乎每个 hook 都有与之同名的.test.ts(x)如 useUsers.test.ts/hooks/users/useUsers.test.ts)进一步说明 hooks 是纯逻辑单元、应当可独立单测。六、Utils本地纯函数就近存放Any pure.tsfunctions that you need in order to process data should be placed in a localutils.tsfile.页面在处理数据时需要一些与 UI/请求无关的纯函数格式化、换算、schema 构造等文档要求就近放在页面目录下的utils.ts。这里的判断标准是纯度不触碰 React 状态、不发起副作用、输入输出确定才叫 util。参照前文的“最低公共祖先”原则先在页面本地utils.ts放一旦多个页面复用就提升到公共位置如src/utils下的 migratedPages.ts 本身就是这类共享工具的实例负责新旧路由映射与 href 构造。仓库里大量模块级utils如 cost-optimization/_components/helpers.ts/cost-optimization/_components/helpers.ts)也都配有同名.test.ts纯函数应当保持“易于测试、必被测试”。七、从零新增一个页面实操清单综合文档与仓库代码新增一个“符合规范”的页面建议按以下步骤执行确定路由名决定 URL 段如/my-page在(dashboard)下新建my-page/目录。创建入口my-page/page.tsxuse clientexport default仅负责获取鉴权/权限与装配视图。创建视图与私有组件MyPageView.tsx必要时与components/或_components/遵循“就近 最低公共祖先”超出 300 行就拆。把逻辑放进my-page/hooks/useXxx.ts纯.ts文件若是 Context Provider 则例外。数据加工放进my-page/utils.ts保持纯函数并为其编写utils.test.ts。同步迁移映射在 migratedPages.ts 中追加侧边栏key: my-page记录让侧边栏、深链与旧?page都能命中新路由删除记录即可回滚。若页面不需要出现在侧边栏可跳过此步。配套测试为page.tsx、关键组件与 hooks 各写一份同目录的.test.tsx/.test.ts参考 page.test.tsx/page.test.tsx) 的 mock 方式。验证命令见 package.json scripts本地next dev启动开发服务器vitest运行全部单测或用vitest run --project component只跑组件测试、--project integration跑集成测试提交前运行npm run lint与npm run format:check。八、小结LiteLLM Dashboard 重构期的代码规范可以浓缩为五条可记忆的规则文件即路由每个侧边栏页面独占一个文件夹内含page.tsx路由组(dashboard)提供布局外壳而不污染 URL。组件哑化组件只从 hooks/props 取数渲染逼近 300 行即拆分。就近 最近公共祖先私有组件放页面内共享代码逐步上移绝不乱放全局目录。hooks 纯.ts归位hooks/逻辑抽 hook除 Context Provider 外一律不含 JSX。纯函数进utils.ts就近存放、保持纯净、务必可测。这套规范配合 MIGRATED_PAGES 迁移映射 的“新增即上线、删除即回滚”机制让控制台可以在不破坏既有链路的条件下把数百个页面与组件安全地从旧式巨型组件逐步迁入全新的 App Router 结构中。为控制台新增能力时请始终以 本 README/README.md) 及(dashboard)下已落地的页面为参照——结构一致的代码才经得起并发协作与长期演进。【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Vue Router从入门到实践:SPA路由的核心机制与踩坑指南

Vue Router从入门到实践:SPA路由的核心机制与踩坑指南

2026/9/8 17:53:20

前阵子有个朋友找我排查一个“页面跳动”的问题。他的Vue项目点菜单跳转时,页面总会闪一下白底,然后新内容才出现。我看完代码,发现问题的根源不在CSS,也不在某段异步逻辑,而是整份代码里完全没有引入vue-router&#…

用 MediaMTX 搭建低延迟直播:从 SRT 推流到 WebRTC 播放的完整指南

用 MediaMTX 搭建低延迟直播:从 SRT 推流到 WebRTC 播放的完整指南

2026/9/8 17:53:20

用 MediaMTX 搭建低延迟直播:从 SRT 推流到 WebRTC 播放的完整指南 【免费下载链接】mediamtx Ready-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, rec…

D20 | 上线与监控:从 Demo 到生产环境的最后一公里

D20 | 上线与监控:从 Demo 到生产环境的最后一公里

2026/9/8 17:53:20

文章目录 D20 | 上线与监控:从 Demo 到生产环境的最后一公里 写在前面 一、Demo 到生产的 3 大鸿沟 鸿沟 ①:可访问性(Accessibility) 鸿沟 ②:稳定性(Reliability) 鸿沟 ③:可观测性(Observability) 二、部署 4 选项 2.1 全景对比 2.2 推荐:中小项目用 Vercel 或阿…

Simulink实现AI模型到MCU的C代码生成与部署指南

Simulink实现AI模型到MCU的C代码生成与部署指南

2026/9/8 18:33:22

写这篇文章前,先分享一个真实的现场:前阵子有朋友拿来一个训练好的电机异常检测模型,在Python里验证集准确率能到98%以上,但下一步就卡住了——他不知道怎么把它放到产线控制器的那颗MCU里去跑。问我要不要把权重导成h文件&#x…

ClickHouse 关联测试选择器深入解析:基于逐测试行级覆盖率的 find_tests.py 架构与实现

ClickHouse 关联测试选择器深入解析:基于逐测试行级覆盖率的 find_tests.py 架构与实现

2026/9/8 18:33:22

ClickHouse 关联测试选择器深入解析:基于逐测试行级覆盖率的 find_tests.py 架构与实现 【免费下载链接】ClickHouse ClickHouse is a real-time analytics database management system 项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse 导读 …

freeCodeCamp CSS Flexbox 教程实战:用 flex-direction: column 让弹性子项垂直堆叠

freeCodeCamp CSS Flexbox 教程实战:用 flex-direction: column 让弹性子项垂直堆叠

2026/9/8 18:33:22

freeCodeCamp CSS Flexbox 教程实战:用 flex-direction: column 让弹性子项垂直堆叠 【免费下载链接】freeCodeCamp freeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free. 项目地址: https://gitcod…

Atmosphere 启动失败怎么办:从黑屏、卡屏到 2162-0002 的完整排查与修复指南

Atmosphere 启动失败怎么办:从黑屏、卡屏到 2162-0002 的完整排查与修复指南

2026/9/8 18:33:22

Atmosphere 启动失败怎么办:从黑屏、卡屏到 2162-0002 的完整排查与修复指南 【免费下载链接】Atmosphere Atmosphre is a work-in-progress customized firmware for the Nintendo Switch. 项目地址: https://gitcode.com/GitHub_Trending/at/Atmosphere 如…

CodeGraph 安装教程:工具调用减少 88%,让 AI 助手不再翻遍整个仓库(100% 本地完整指南)

CodeGraph 安装教程:工具调用减少 88%,让 AI 助手不再翻遍整个仓库(100% 本地完整指南)

2026/9/8 18:33:21

CodeGraph 安装教程:工具调用减少 88%,让 AI 助手不再翻遍整个仓库(100% 本地完整指南) 【免费下载链接】codegraph Pre-indexed code knowledge graph, auto syncs on code changes, for Claude Code, Codex, Gemini, Cursor, Op…

ip2region 离线IP定位库快速上手指南:IPv4/IPv6 微秒级查询完整教程

ip2region 离线IP定位库快速上手指南:IPv4/IPv6 微秒级查询完整教程

2026/9/8 18:23:21

ip2region 离线IP定位库快速上手指南:IPv4/IPv6 微秒级查询完整教程 【免费下载链接】ip2region Ip2region is an offline IP-to-Region localization library and IP data management framework with both IPv4 and IPv6 supports, 10-microsecond level query eff…

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

2026/9/7 20:21:46

本文首发于“生态学者”!从“湿地面积”到“土壤碳密度”:为什么需要重新认识潮汐湿地蓝碳变化?潮汐湿地位于陆地与海洋的交汇地带,包括红树林、盐沼和潮滩,是全球重要的蓝碳生态系统。其土壤能够长期储存大量有机碳&a…

adb抓包

adb抓包

2026/9/8 4:55:53

前言 本文介绍如何通过 tcpdump 在 Android 手机上抓取网络数据包,并在电脑端使用 Wireshark 进行分析。适用于需要排查 App 网络请求、分析接口调用或调试网络问题的开发与测试场景。1. 手机要有 root 权限2. 下载 tcpdump3. adb push C:\Users\zhangkuixun\Downlo…

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

2026/9/7 8:03:37

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战 在云原生基础设施中,容器镜像体积直接决定了服务的部署速度与弹性扩容敏捷度。对于传统的 Go / Java 微服务,镜像体积通常被严格控制在 50MB 到 200MB 以内,拉取镜像只…

芯片良率波动可视化:动画拆解工艺因果,重建客户信任

芯片良率波动可视化:动画拆解工艺因果,重建客户信任

2026/9/8 0:02:30

芯片这个行业有个不太被人摆到台面上、但几乎每天都在发生的场景:客户拿着一条良率曲线截图问你,这批货的良率怎么掉了三个点,是不是工艺出问题了,产生的不良会不会流到他们产线上去。你解释了半天,客户似懂非懂&#…

PyTorch DataLoader参数冲突:sampler与shuffle互斥的根源与正确写法

PyTorch DataLoader参数冲突:sampler与shuffle互斥的根源与正确写法

2026/9/8 0:02:30

ValueError: sampler option is mutually exclusive with shuffle,这个报错我在 PyTorch 的 DataLoader 上至少见过几十次了,而且很有意思的是,它经常不是新手专属——很多写了好几年模型的老手,在从单机改成自定义采样器&#xf…

中国车企再破谣言,GAC吉利零跑获欧盟安全五星

中国车企再破谣言,GAC吉利零跑获欧盟安全五星

2026/9/8 0:02:30

有人可能在网上开着皮卡拍视频,声称中国电动车不仅性能不如美国大排量车型,安全性也堪忧。然而事实恰恰相反,GAC、吉利和零跑最新推出的电动车型在极为严苛的欧盟新车安全评鉴(Euro NCAP)测试中全部斩获满分。就在特斯…

远程协作的工作台整理

远程协作的工作台整理

2026/9/8 4:23:39

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/8 3:19:39

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/8 4:00:23

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…