2023年4月6日,星期四
Next.js 13.3
发布者Next.js 13.3 增加了广受欢迎的社区请求功能,包括
- 基于文件的元数据 API:动态生成站点地图、robots、网站图标等。
- 动态 Open Graph 图像:使用 JSX、HTML 和 CSS 生成 OG 图像。
- App Router 的静态导出:服务器组件的静态/单页应用程序 (SPA) 支持。
- 并行路由和拦截:App Router 的高级路由功能。
立即运行以下命令更新
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
我们即将在下一个小版本中将 App Router 标记为稳定版,并将重心转移到优化性能、增强行为和修复错误上。
虽然我们仍在开发一些功能(如 Mutations),但我们预计这些功能不会影响其他 App Router 功能的 API 表面。我们很高兴看到您使用 App Router 构建的内容,并期待您的反馈。
基于文件的元数据 API
在 Next.js 13.2 中,我们宣布了新的元数据 API,允许您通过从布局或页面导出元数据对象来定义元数据(例如,HTML head
元素内的 title
、meta
和 link
标签)。
// either Static metadata
export const metadata = {
title: 'Home',
};
// Output:
// <head>
// <title>Home</title>
// </head>
// or Dynamic metadata
export async function generateMetadata({ params, searchParams }) {
const product = await getProduct(params.id);
return { title: product.title };
}
// Output:
// <head>
// <title>My Unique Product</title>
// </head>
export default function Page() {}
除了基于配置的元数据之外,元数据 API 现在还支持新的文件约定,使您可以方便地自定义页面,以改进 SEO 和在网络上的分享
opengraph-image.(jpg|png|svg)
twitter-image.(jpg|png|svg)
favicon.ico
icon.(ico|jpg|png|svg)
sitemap.(xml|js|jsx|ts|tsx)
robots.(txt|js|jsx|ts|tsx)
manifest.(json|js|jsx|ts|tsx)
例如,您可以使用基于文件的元数据为您的应用程序添加网站图标,并为您的 /about
页面添加 Open Graph 图像
app
├── favicon.ico
├── layout.js
├── page.js
└── about
├── opengraph-image.jpg
└── page.js
Next.js 将在生产环境中自动提供带有哈希值(用于文件名)的这些文件以进行缓存,并使用正确的元数据信息(例如资产的 URL、文件类型和图像大小)更新相关的 head
元素。
// Visiting "/"
<link rel="icon" href="<computedUrl>"/>
// Visiting "/about"
<link rel="icon" href="<computedUrl>"/>
<meta property="og:image" content="<computedUrl>" type="<computedType>" ... />
向应用程序添加静态文件通常是最简单的方法,但在某些情况下,您可能需要动态创建文件。对于每个静态文件约定,都有一个随附的动态 (.js|.jsx|.ts|.tsx)
变体,允许您编写代码来生成文件。
例如,虽然您可以添加静态的 sitemap.xml
文件,但大多数站点都有一些页面是使用外部数据源动态生成的。要生成动态站点地图,您可以添加一个 sitemap.js
文件,该文件返回动态路由的数组。
export default async function sitemap() {
const res = await fetch('https://.../posts');
const allPosts = await res.json();
const posts = allPosts.map((post) => ({
url: `https://acme.com/blog/${post.slug}`,
lastModified: post.publishedAt,
}));
const routes = ['', '/about', '/blog'].map((route) => ({
url: `https://acme.com${route}`,
lastModified: new Date().toISOString(),
}));
return [...routes, ...posts];
}
通过基于配置和新的基于文件的选项,您现在拥有一个全面的元数据 API,可以覆盖静态和动态元数据。
元数据 API 在 13.3 版本中适用于 App Router (app
)。它在 pages
目录中不可用。了解更多关于基于文件的元数据并查看 API 参考。
动态 Open Graph 图像生成
六个月前,我们发布了 @vercel/og 和 Satori,这些库允许您使用 JSX、HTML 和 CSS 动态生成图像。
@vercel/og
在 Next.js Conf 上进行了测试,为每位与会者生成了超过 100,000 张动态门票图像。 随着 @vercel/og 在 Vercel 客户中得到广泛采用,并且自发布以来下载量超过 900,000 次,我们很高兴将动态生成的图像引入到所有 Next.js 应用程序中,而无需外部软件包。
您现在可以从 next/server
导入 ImageResponse
来生成图像
import { ImageResponse } from 'next/server';
export const size = { width: 1200, height: 600 };
export const alt = 'About Acme';
export const contentType = 'image/png';
export const runtime = 'edge';
export default function og() {
return new ImageResponse();
// ...
}
ImageResponse
自然地与其他 Next.js API(包括路由处理程序和基于文件的元数据)很好地集成。 例如,您可以在 opengraph-image.tsx
文件中使用 ImageResponse
以在构建时或在请求时动态生成 Open Graph 和 Twitter 图像。
了解更多关于 Image Response API。
App Router 的静态导出
Next.js App Router 现在支持完全静态导出。
您可以从静态站点或单页应用程序 (SPA) 开始,然后在以后选择升级以使用需要服务器的 Next.js 功能。
当运行 next build
时,Next.js 为每个路由生成一个 HTML 文件。 通过将严格的 SPA 分解为单独的 HTML 文件,Next.js 可以避免在客户端加载不必要的 JavaScript 代码,从而减小捆绑包大小并加快页面加载速度。
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
output: 'export',
};
module.exports = nextConfig;
静态导出适用于 app
路由器的新功能,包括静态路由处理程序、Open Graph 图像和 React 服务器组件。
例如,服务器组件将在构建期间运行,类似于传统的静态站点生成,将组件渲染为静态 HTML 以用于初始页面加载,并将静态有效负载用于客户端路由之间的导航。
以前,要在 pages
目录中使用静态导出,您需要运行 next export
。但是,使用 next.config.js
选项,当 output: 'export'
设置时,next build
将输出一个 out
目录。 您可以为 app
路由器和 pages
目录使用相同的配置。 这意味着不再需要 next export
。
借助高级静态导出支持,您将在开发过程的早期(next dev
)收到错误,例如,当尝试使用需要服务器的动态函数(如 cookies()
或 headers()
)时。
了解更多关于 静态导出。
并行路由和拦截
Next.js 13.3 引入了新的动态约定,允许您实现高级路由案例:并行路由和拦截路由。 这些功能使您可以在同一视图中显示多个页面,例如复杂的仪表板或模态框。
使用并行路由,您可以在同一视图中同时渲染一个或多个页面,这些页面可以独立导航。 它也可以用于有条件地渲染页面。
并行路由使用命名的 “插槽” 创建。 插槽使用 @folder
约定定义
dashboard
├── @user
│ └── page.js
├── @team
│ └── page.js
├── layout.js
└── page.js
同一路由段中的布局接受插槽作为 props
export default async function Layout({ children, user, team }) {
const userType = getCurrentUserType();
return (
<>
{userType === 'user' ? user : team}
{children}
</>
);
}
在上面的示例中,@user
和 @team
并行路由插槽(显式)根据您的逻辑有条件地渲染。 children
是一个隐式路由插槽,不需要映射到 @folder
。 例如,dashboard/page.js
等同于 dashboard/@children/page.js
。
拦截路由允许您在当前布局中加载新路由,同时“掩盖”浏览器 URL。 当保持当前页面的上下文很重要时,这非常有用,例如通过模态框展开 feed 中的照片,其中 feed 保留在模态框的背景中。
可以使用 (..)
约定定义拦截路由,类似于相对路径 ../
。 您还可以使用 (...)
约定创建相对于 app
目录的路径。
feed
├── @modal
│ └── (..)photo
│ └── [id]
│ └── page.tsx
├── page.tsx
└── layout.tsx
photo
└── [id]
└── page.tsx
在上面的示例中,单击用户个人资料中的照片将在客户端导航期间在模态框中打开照片。 但是,刷新或共享页面将使用其默认布局加载照片。

这解决了您在创建模态框时可能遇到的挑战,例如使模态框内容可通过 URL 共享、防止页面刷新时上下文丢失以及使用后退和前进导航关闭和重新打开模态框。
其他改进
- 设计更新: Next.js 主页 和 案例展示 已使用新设计进行了刷新。
- Turbopack: 增加了对中间件、所有
next/font
选项以及使用服务器组件进行流式传输的支持,因为它即将进入 beta 版 (查看演示)。 我们还修复了在成熟的 Next.js 应用程序(如 vercel.com 和 nextjs.org 上进行试用时发现的其他错误。 了解更多。 next.config.js
的快速刷新: 现在更改next.config.js
将自动重启本地开发服务器。 这扩展了对.env
、.env.*
、jsconfig.json
、tsconfig.json
配置文件自动重新加载的支持。- 可访问性: App Router 现在包含来自
pages
的路由公告。 此功能向屏幕阅读器和其他辅助技术公告客户端路由转换。 了解更多。 - 静态类型链接:在
next.config.js
中设置的redirects
和rewrites
现在在类型检查期间被考虑在内。 了解更多。 create-next-app
的 Tailwind CSS: 当使用npx create-next-app@latest
启动新项目时,您现在可以选择性地选择 Tailwind CSS,或使用--tailwind
标志,以使用此样式解决方案预配置您的应用程序。- 路由处理程序: 现在,使用
export default
而不是支持的 HTTP 动词会在route.ts
中抛出一个有用的错误。 了解更多关于路由处理程序的信息。 - 图像:
next/image
现在支持fetchPriority="high"
属性。 - 元数据: 先前的元数据 API (
head.js
) 在 13.2 中已弃用,现已移除。 请改用通过 元数据 API 内置的 SEO 支持。 - 将文件夹排除在路由之外: 在文件夹前缀添加 _ 以将其和任何子段排除在路由之外。 例如,
app/_dashboard/page.tsx
将不可路由。 - App Router: 我们添加了一个新的
useParams
客户端组件钩子,用于读取给定路由段的动态参数。 了解更多。 - 改进的样式表加载: Next.js 现在实现了 React 的 Suspensey CSS,它修复了许多关于 CSS 加载和未样式化内容闪烁的问题,尤其是在导航期间。
- 改进的未找到处理: 除了捕获预期的
notFound()
错误之外,根app/not-found.js
文件还将处理整个应用程序的任何不匹配的 URL。 这意味着访问您的应用程序未处理的 URL 的用户将看到app/not-found.js
文件导出的 UI。 了解更多。 - 改进的客户端路由器缓存:
router.refresh()
现在将使整个缓存失效,并且搜索参数现在是缓存键的一部分,允许在两个搜索参数(例如/?search=leerob
和/?search=tim
)之间导航,以正确恢复依赖于参数的内容。
社区
Next.js 是超过 2,600 位个人开发者、Google 和 Meta 等行业合作伙伴以及我们在 Vercel 的核心团队共同努力的成果。 凭借每周超过 420 万次的 npm 下载量和 104,000+ 个 GitHub 星星,Next.js 已成为构建 Web 的最流行方式之一。
加入 GitHub Discussions、Reddit 和 Discord 社区。
此版本由以下人员发布
- Next.js 团队:Andrew、Balazs、Hannes、Jan、Jiachi、Jimmy、JJ、Josh、Sebastian、Shu、Steven、Tim 和 Wyatt。
- Turbopack 团队:Alex、Donny、Justin、Leah、LongYinan、Maia、OJ、Tobias 和 Will。
以及以下贡献者:@shuding, @huozhi, @sokra, @hanneslund, @JesseKoldewijn, @kaguya3222, @yangshun, @ijjk, @konomae, @Brooooooklyn, @jridgewell, @zlrlyy, @JohnDaly, @abhiyandhakal, @benjie, @johnnyomair, @nk980113, @dirheimerb, @DerTimonius, @DuCanhGH, @padmaia, @stafyniaksacha, @Gladowar, @zek, @jankaifer, @styfle, @balazsorban44, @wbinnssmith, @chibicode, @ForsakenHarmony, @franktronics, @FSaldanha, @Schniz, @raisedadead, @AdamKatzDev, @wyattjoh, @leerob, @meesvandongen, @vladikoff, @feedthejim, @tka5, @pyjun01, @gdborton, @M3kH, @aretrace, @shivanshubisht, @alexkirsz, @agrattan0820, @vinaykulk621, @heyitsuzair, @mrkldshv, @timneutkens, @furkanmavili, @swaminator, @EndangeredMassa, @DevEsteves, @rishabhpoddar, @schehata, @molebox, @dlehmhus, @akshaynox, @sp00ls, @janicklas-ralph, @tomryanx, @kwonoj, @karlhorky, @kdy1, @dante-robinson, @lachlanjc, @ianmacartney, @hotters, @isaackatayev, @insik-han, @jayair, @ivanhofer, @javivelasco, @SukkaW, @visshaljagtap, @imranbarbhuiya, @nivak-monarch, @HarshaVardhanReddyDuvvuru, @ianldgs, @ricardofiorani, @swarnava, 和 @gustavostz。