2023年4月6日,星期四
Next.js 13.3
发布者Next.js 13.3 添加了社区期待已久的热门功能,包括
- 基于文件的元数据 API:动态生成网站地图、robots、favicon 等。
- 动态 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)
例如,您可以使用基于文件的方法添加应用的 favicon 和 /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 客户的广泛采用以及自发布以来的 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 图片。
详细了解 图像响应 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。当保持当前页面的上下文很重要时,这很有用,例如通过模态框扩展提要中的照片,其中提要保留在模态框的背景中。
拦截路由可以使用(..)
约定定义,类似于相对路径../
。您还可以使用(...)
约定创建相对于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"
属性。 - 元数据:先前用于元数据(
head.js
)的 API(在 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 是超过 2600 位独立开发人员、谷歌和 Meta 等行业合作伙伴以及我们在 Vercel 的核心团队共同努力的结果。Next.js 每周拥有超过 420 万次 npm 下载量和超过 104,000 个 GitHub 星标,是构建 Web 的最流行方式之一。
加入社区,访问 GitHub 讨论、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。