This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
服务器渲染
了解如何使用服务器端渲染(SSR)在请求时动态渲染 Expo Router 路由。
重要 服务器渲染在 SDK 58 及更高版本中是稳定的。对于 SDK 55–57,请在
expo-router配置插件中启用unstable_useServerRendering。生产环境使用需要一个已部署的服务器。
服务器端渲染(SSR)会在每次请求时动态生成 HTML,而不是像静态渲染那样在构建时预生成 HTML。本指南将引导你为你的 Expo Router 应用启用服务器渲染。
🌐 Server-side rendering (SSR) generates HTML dynamically on each request, as opposed to static rendering, which pre-renders HTML at build time. This guide walks you through enabling server rendering for your Expo Router app.
信息 使用服务器端渲染时,数据加载器 会在服务器上为每个请求执行,结果会嵌入到 HTML 响应中。
设置
🌐 Setup
要保持 SDK 57 及更早版本中 web.output: "server" 的行为,可以在 expo-router 配置插件中使用 web.output: "static" 搭配 apiRoutes: true。这会将 预渲染的 HTML 与 API 路由 结合起来。
🌐 To keep the behavior of web.output: "server" from SDK 57 and earlier, use web.output: "static" with apiRoutes: true in the expo-router config plugin. This combines prerendered HTML with API routes.
1
在你的项目的应用配置中将 web.output 设置为 server 来启用服务器渲染:
🌐 Set web.output to server in your project's app config to enable server rendering:
2
启动开发服务器:
🌐 Start the development server:
生产
🌐 Production
要将你的应用导出用于生产环境,请运行导出命令:
🌐 To export your app for production, run the export command:
这会创建一个包含你的服务器渲染应用的 dist 目录。与静态渲染不同,不会预先生成 HTML 文件。相反,输出包括如下所示的类似目录结构:
🌐 This creates a dist directory with your server-rendered application. Unlike static rendering, no HTML files are pre-generated. Instead, the output includes a similar directory structure as shown below:
distclient_expostaticjswebentry-[hash].jscss[name]-[hash].cssserver_exporoutes.jsonserverrender.js上面的输出包括 dist 目录下的以下目录:
🌐 In output above includes the following directories inside dist directory:
- client 目录:包含用于客户端渲染的 JavaScript 和 CSS 包
- server 目录:包含路由清单和服务器渲染模块
你可以通过运行以下命令并在浏览器中打开链接的 URL 来本地测试生产版本:
🌐 You can test the production build locally by running the following command and opening the linked URL in your browser:
上述命令启动了一个本地服务器,在每次请求时渲染页面,从而模拟生产环境。
🌐 The above command starts a local server that renders pages on each request, simulating a production environment.
动态路由
🌐 Dynamic routes
使用服务器渲染时,动态路由会即时渲染,不需要 generateStaticParams 导出,应将其移除。如果你的路由文件导出了 generateStaticParams,这些路由将会以动态方式处理。路由会在请求时使用 URL 中的实际参数进行渲染。
🌐 With server rendering, dynamic routes are rendered on the fly, and the generateStaticParams export is not needed and should be removed. If your route file exports generateStaticParams, those routes will be handled dynamically instead. The route is rendered at request time with the actual parameters from the URL.
在上述示例中,当应用用户访问 /blog/my-post 时,页面会在服务器上渲染,并且 id 被设置为 "my-post"。
🌐 In the above example, when the app user visits /blog/my-post, the page is rendered on the server with id set to "my-post".
根 HTML
🌐 Root HTML
你可以通过创建 src/app/+html.tsx 文件来自定义根 HTML 文档。这个组件会封装所有路由,并且仅在服务器上运行。
🌐 You can customize the root HTML document by creating a src/app/+html.tsx file. This component wraps all routes and runs only on the server.
expo-router/html 的 useServerDocumentContext 钩子提供了服务器渲染器注入到文档中的元数据和资源节点。你必须将这些值展开到你的 HTML 中,以确保响应中包含元数据、字体、CSS 和 JavaScript 包:
🌐 The useServerDocumentContext hook from expo-router/html provides metadata and asset nodes that the server renderer injects into the document. You must spread these values into your HTML to ensure metadata, fonts, CSS, and JavaScript bundles are included in the response:
htmlAttributes:要添加到<html>元素的属性bodyAttributes:要添加到<body>元素的属性headNodes:<head>元素的 React 节点(元数据、CSS 和其他资源)bodyNodes:<body>元素的 React 节点(需要字体和 JavaScript 包进行 hydration)。如果省略这些,应用就无法完成 hydration,也无法变得可交互。
信息 在创建自定义 +html.tsx 模板时,你必须使用
useServerDocumentContext返回给你的所有属性。否则,你的服务器端渲染 HTML 可能会出现损坏,或者你的应用可能无法正常运行。
+html.tsx 文件仅由服务器渲染器使用,从不被客户端代码使用。这意味着:
🌐 The +html.tsx file is only used by the server renderer and never by client code. This means:
- 它将在服务器渲染期间由
expo-server运行 - 它不会在客户端重新水化,并且应该只使用
useServerDocumentContextReact 钩子 - 你不能在
+html.tsx中导入全局 CSS(请使用 Root Layout 来添加样式) - 你不能在你的
+html.tsx中调用像window或document这样的浏览器 API pathname和params属性包含渲染的路由的路径名和 URL 参数。在 SDK 58 及更高版本 可用。
所有 +html.tsx 组件都应在它们的 JSX 内容中渲染它们接收到的 children 属性。
🌐 All +html.tsx components are expected to render the children prop they receive in their JSX content.
元数据
🌐 Metadata
路由可以导出一个 generateMetadata 函数来定义每个页面的元数据,例如标题、描述和 Open Graph 标签。该函数在渲染开始之前在服务器上运行,其结果通过你在 根 HTML 组件中使用 useServerDocumentContext 提供的 headNodes 注入到 HTML 文档的 <head> 中。
🌐 Routes may export a generateMetadata function to define per-page metadata such as title, description, and Open Graph tags. This function runs on the server before rendering begins, and its result is injected into the <head> of the HTML document via the headNodes provided by useServerDocumentContext in your Root HTML component.
从你的路由文件中导出一个 generateMetadata 函数,并返回一个 Metadata 对象。该函数接收传入的请求和路由参数,你可以使用它们动态生成元数据:
🌐 Export a generateMetadata function from your route file and return a Metadata object. The function receives the incoming request and route parameters, which you can use to generate metadata dynamically:
generateMetadata 函数在服务器上执行,并从客户端包中去除,类似于 数据加载器。有关支持的元数据字段的完整列表,请参阅 expo-server API 参考中的 Metadata 类型。
🌐 The generateMetadata function executes on the server and is stripped from the client bundle, similar to data loaders. For a full list of supported metadata fields, see the Metadata type in the expo-server API reference.
在服务器渲染中使用 <Head>
🌐 Using <Head> with server rendering
你也可以使用来自 expo-router/head 的 <Head> 组件来添加 <meta> 标签。两种方法可以在同一路由中共存。然而,generateMetadata 是服务端渲染推荐的方法,因为它在 HTML 流开始之前就解析元数据,从而确保 <meta> 标签包含在响应的最早字节中。<Head> 可用于在应用完成水合后动态更新 <meta> 标签。
🌐 You can also use the <Head> component from expo-router/head to add <meta> tags. Both approaches can co-exist in the same route. However, generateMetadata is the recommended approach for server rendering because it resolves metadata before the HTML stream begins, ensuring that <meta> tags are included in the earliest bytes of the response. <Head> can be used to update <meta> tags dynamically after the app has hydrated.
部署
🌐 Deployment
服务端渲染需要一个运行时服务器来在每次请求时渲染页面。使用服务器端渲染的 Expo 应用无法部署到像 GitHub Pages 这样的静态托管服务。
🌐 Server-side rendering requires a runtime server to render pages on each request. Server-side rendered Expo apps cannot be deployed to static hosting services like GitHub Pages.
支持的平台
🌐 Supported platforms
示例:使用 EAS 托管进行部署
EAS Hosting 开箱即支持服务器端渲染。导出你的应用并使用以下方式部署:
🌐 EAS Hosting supports server rendering out of the box. Export your app and deploy with:
与静态渲染的比较
🌐 Comparison with static rendering
常见问题
🌐 Common questions
我可以在服务器渲染中使用数据加载器吗?
是的。服务器端渲染可以与 数据加载器 配合使用,在渲染之前在服务器上获取数据。
🌐 Yes. Server rendering works with data loaders to fetch data on the server before rendering.
我可以混合使用服务器渲染和静态渲染吗?
目前,Expo Router 不支持在同一个项目中混合服务器渲染和静态渲染。请根据你的需求选择一种输出模式。
🌐 Currently, Expo Router does not support mixing server and static rendering in the same project. Choose a single output mode based on your requirements.
我如何缓存服务器渲染的响应?
缓存由服务器或CDN级别处理。配置你的部署平台,根据URL模式或缓存头来缓存响应。
🌐 Caching is handled at the server or CDN level. Configure your deployment platform to cache responses based on URL patterns or cache headers.
服务器渲染可以与 API 路由一起使用吗?
是的。API 路由 与渲染模式无关。它们始终在服务器上执行。
🌐 Yes. API routes work independently of the rendering mode. They are always executed on the server.