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 上進行了測試,為每位與會者產生超過 10 萬張動態票券圖片。由於 Vercel 客戶廣泛採用,並且自發布以來下載次數超過 90 萬次,我們很高興將動態產生的圖片引入所有 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 引入了新的動態慣例,讓您可以實作進階路由案例:平行路由和攔截路由。這些功能可讓您在同一個視圖中顯示多個頁面,例如複雜的儀表板或彈出視窗。
透過平行路由,您可以同時在同一個視圖中呈現一個或多個可獨立導覽的頁面。它也可以用於有條件地呈現頁面。
平行路由是使用命名的 「插槽」(slots) 建立的。插槽是使用 @資料夾
慣例定義的
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
是一個隱含的路由插槽,不 需要對應到 @資料夾
。例如,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.js 應用程式上進行「試用體驗」時發現的其他錯誤。深入了解。 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
用戶端元件 Hook,以讀取給定路由區段的動態參數。深入了解。 - 改進的樣式表載入: 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 核心團隊共同努力的成果。Next.js 每週 npm 下載次數超過 420 萬次,GitHub 星星數超過 104,000 顆,是建構 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。