方法一:直接在 page.tsx 中使用 async 函数加载数据
在 App Router 中,页面组件本身就是一个可以是 async 的函数。你可以在其中请求远程 JSON 文件或 API 并将数据作为 props 注入到组件内:
// app/page.tsx
import React from 'react'
export default async function Page() {
// 例如:远程语言包和皮肤 JSON 请求
const [langRes, themeRes] = await Promise.all([
fetch('https://your-cdn.com/i18n/zh.json'),
fetch('https://your-cdn.com/theme/default.json'),
])
const langData = await langRes.json()
const themeData = await themeRes.json()
return (
<main style={{ backgroundColor: themeData.bgColor }}>
<h1>{langData.title}</h1>
</main>
)
}
方法二:将加载逻辑写在 layout.tsx 中,全局注入
如果语言包和皮肤信息是整个 app 都需要的,推荐将数据加载逻辑写在 layout.tsx 中,并通过 props 传递给子组件。
示例结构:
/app
├─ layout.tsx ✅ 读取全局数据(语言包、皮肤)
├─ page.tsx ✅ 使用注入的数据
layout.tsx 示例:
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const langRes = await fetch('https://your-cdn.com/i18n/zh.json')
const themeRes = await fetch('https://your-cdn.com/theme/default.json')
const lang = await langRes.json()
const theme = await themeRes.json()
return (
<html>
<body style={{ background: theme.bgColor }}>
{/* 使用 React context 或 props 传递数据 */}
<LangProvider value={lang}>
<ThemeProvider value={theme}>
{children}
</ThemeProvider>
</LangProvider>
</body>
</html>
)
}
方法三:结合中间件进行重定向注入
中间件适用于权限跳转、重定向,不适合加载大数据(如 JSON 语言包、主题皮肤等),因为它运行在 Edge Runtime,不能用 Node API,且不能传递复杂数据到组件中。
总结注入策略对比:
| 注入方式 | 是否推荐 | 是否支持 SSR | 适用场景 |
|---|---|---|---|
| page.tsx 中直接加载 | ✅✅✅ | ✅ | 页面级数据,接口+文件注入 |
| layout.tsx 中加载 | ✅✅✅ | ✅ | 全局数据,如皮肤、语言、配置 |
| middleware.ts 中处理 | 🚫 | ❌ | 用于跳转/权限,不能传数据 |