Back返回部落格

Next.js 13.3

Next.js 13.3 引入了動態 Open Graph 圖片、進階靜態導出、平行路由與攔截路由、OTEL 支援等新功能。

Next.js 13.3 新增了社群高度期待的功能,包括:

立即更新執行:

終端機
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,允許您透過從佈局或頁面導出 Metadata 物件來定義元資料(例如 HTML head 元素中的 titlemetalink 標籤)。

layout.js 或 page.js
// 靜態元資料
export const metadata = {
  title: '首頁',
};
// 輸出:
// <head>
//	 <title>首頁</title>
// </head>
 
// 或動態元資料
export async function generateMetadata({ params, searchParams }) {
  const product = await getProduct(params.id);
  return { title: product.title };
}
// 輸出:
// <head>
//	 <title>我的獨特產品</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 元素。

// 訪問 "/"
<link rel="icon" href="<計算後的Url>"/>
 
// 訪問 "/about"
<link rel="icon" href="<計算後的Url>"/>
<meta property="og:image" content="<計算後的Url>" type="<計算後的類型>" ... />

將靜態檔案添加到應用程式通常是最簡單的方法,但有時您可能需要動態建立檔案。對於每個靜態檔案約定,都有一個對應的動態 (.js|.jsx|.ts|.tsx) 變體,允許您編寫程式碼來生成檔案。

例如,雖然您可以添加靜態 sitemap.xml 檔案,但大多數網站都有一些頁面是使用外部資料來源動態生成的。要生成動態網站地圖,您可以添加一個 sitemap.js 檔案,該檔案返回您的動態路由陣列。

app/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/ogSatori,這些函式庫允許您使用 JSX、HTML 和 CSS 動態生成圖片。

@vercel/ogNext.js Conf 中經受了考驗,為每位與會者生成了超過 100,000 張動態門票圖片。自從發布以來,Vercel 客戶廣泛採用並下載超過 900,000 次,我們很高興能將動態生成的圖片帶給所有 Next.js 應用程式,而無需外部套件。

您現在可以從 next/server 導入 ImageResponse 來生成圖片:

/app/about/opengraph-image.tsx
import { ImageResponse } from 'next/server';
 
export const size = { width: 1200, height: 600 };
export const alt = '關於 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 程式碼,減少套件大小並實現更快的頁面載入。

next.config.js
/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  output: 'export',
};
 
module.exports = nextConfig;

靜態導出與 app router 的新功能(包括靜態路由處理器、Open Graph 圖片和 React 伺服器元件)一起使用。

例如,伺服器元件將在構建期間運行,類似於傳統的靜態網站生成,將元件渲染為初始頁面載入的靜態 HTML 和路由之間客戶端導航的靜態有效負載。

以前,要在 pages 目錄中使用靜態導出,您需要運行 next export。然而,使用 next.config.js 選項,當設置 output: 'export' 時,next build 將輸出一個 out 目錄。您可以對 app router 和 pages 目錄使用相同的配置。這意味著不再需要 next export

透過進階靜態導出支援,您將在開發過程 (next dev) 中更早地收到錯誤,例如嘗試使用需要伺服器的動態函式(如 cookies()headers())時。

了解更多關於 靜態導出

平行路由與攔截路由

Next.js 13.3 引入了新的動態約定,允許您實現進階路由案例:平行路由和攔截路由。這些功能使您可以在同一視圖中顯示多個頁面,例如複雜的儀表板或模態框。

使用平行路由,您可以同時在 同一視圖 中渲染一個或多個可以獨立導航的頁面。它也可以用於條件式渲染頁面。

平行路由使用命名 「插槽」 建立。插槽使用 @folder 約定定義:

dashboard
├── @user
│   └── page.js
├── @team
│   └── page.js
├── layout.js
└── page.js

同一路由區段中的佈局將插槽作為屬性接收:

app/dashboard/layout.js
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

在上面的例子中,從用戶個人檔案點擊照片將在客戶端導航期間在模態框中打開照片。然而,刷新或分享頁面將載入具有其預設佈局的照片。

平行路由與攔截路由實現了類似 Instagram 的模態路由。

平行路由和攔截路由實現了類似 Instagram 的模態路由。

這解決了您在建立模態框時可能遇到的挑戰,例如透過 URL 分享模態內容、防止刷新頁面時丟失上下文,以及透過向後和向前導航關閉和重新打開模態框。

更多範例和行為,請參閱 平行路由攔截路由文件

其他改進

  • 設計更新: Next.js 首頁展示 已更新為新設計。
  • Turbopack: 新增了對中介軟體 (Middleware)、所有 next/font 選項和伺服器元件串流的支援,即將進入測試版(查看演示)。我們還修復了在成熟 Next.js 應用程式(如 vercel.comnextjs.org)中發現的其他錯誤。了解更多
  • next.config.js 的快速刷新:next.config.js 的更改現在會自動重新啟動本地開發伺服器。這擴展了對 .env.env.*jsconfig.jsontsconfig.json 配置檔的自動重新載入。
  • 無障礙性: App Router 現在包含來自 pages 的路由公告。此功能向螢幕閱讀器和其他輔助技術宣布客戶端路由轉換。了解更多
  • 靜態類型連結: next.config.js 中設置的 redirectsrewrites 現在在類型檢查期間被考慮。了解更多
  • 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 載入和無樣式內容閃爍的問題,特別是在導航期間。
  • 改進的 404 處理: 除了捕獲預期的 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 是構建網路最受歡迎的方式之一。

加入 GitHub DiscussionsRedditDiscord 上的社群。

此版本由以下人員帶給您:

以及以下貢獻者:@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。