blog.markkulab.net Open in urlscan Pro
2a06:98c1:3120::3  Public Scan

URL: https://blog.markkulab.net/nextjs-upgrade-app-route/?fbclid=IwAR1BsVZYgM3APBugtiUwkJbvyhdyzPauZW1jFO_bSLsZot6VzEpTLi-8Xgs
Submission: On May 29 via api from US — Scanned from NL

Form analysis 0 forms found in the DOM

Text Content

首頁 關於我


Frontend
NEXTJS 13.3.4 昇級踩坑筆記,Server side component 時代來臨 - migrate page route to app
route
Mark Ku
May 27, 2023
1 min



前言

為了重寫我們的德國電商網站,我進行了深入評估,並決定採用 Next js 的最新穩定版本13.4.3,這個版本的 SEO meta api和server
side component功能具有極高的吸引力,且加上未來許多 NextJS的功能都將以app route 上,因此我們選擇採用app
route對我們來說毫無疑問。


1 SERVER SIDE COMPONENT


1.1 APP FOLDER 下的元件或頁面,預設都是 SERVER SIDE COMPONENT

 * By default, all components on NextJS 13 inside the App folder are server
   components. And Server Components cannot use client features such as
   useState, useEffect, etc.

 * For now, to use third-party components the solution is to create a wrapper
   for each client component that doesn’t include the directive ‘use client’:


1.2 SERVER SIDE COMPONENT 好處

Server Components的運作方式是在伺服器上進行渲染,從而只傳遞需要的JS
Bundle程式碼至用戶端瀏覽器,不必要的js則不會被下載,這個特性能有效地減少網路傳輸量,提高效能和速度。


1.3限制

不能使用 useState 和 useReducer、 Hooks、useEffect、useLayoutEffect


1.4 如果要使用 CLINET SIDE COMPONENT ,每個 COMPONENT 都要加上這一行

"use client";
import xxx
...


2 新 USEROUTE

import { useRouter, useParams, usePathname ,useSearchParams } from 'next/navigation';


2.1 在新的 USEROUTE ,並沒有 LOCALE

const { locale } = useRouter();


2.2 路由及資料夾結構

這種改動的方式,更直觀從資料夾結構了解是頁面還是元件。

UrlPage routeApp
route//page/index.tsx/app/page.tsx/about-us/page/about-us.tsx/app/about-us/page.tsx

P.S. 附錄有寫了一個Powershell 快速將 page folder 遷移到 app folder


2.3 要資料的方式調整

新的寫法並不透過 getStaticProps、getServerSideProp 去要資料

async func getData() {
  const res = await fetch ("https://api.xxx.com/...");
  return res.json();
}


export default async function About() {
  const name = await getData();
  return "...";
}


3. 提供 META API 替代 NEXT/HEAD,更容易的針對每個頁面給不同 SEO 的 META DATA


3.1 STATIC METADATA

import { Metadata } from 'next';
 
export const metadata: Metadata = {
  title: '...',
  description: '...',
};
 
export default function Page() {}


3.2 DYNAMIC METADATA

import { Metadata, ResolvingMetadata } from 'next';
 
type Props = {
  params: { id: string };
  searchParams: { [key: string]: string | string[] | undefined };
};
 
export async function generateMetadata(
  { params, searchParams }: Props,
  parent?: ResolvingMetadata,
): Promise<Metadata> {
  // read route params
  const id = params.id;
 
  // fetch data
  const product = await fetch(`https://.../${id}`).then((res) => res.json());
 
  // optionally access and extend (rather than replace) parent metadata
  const previousImages = (await parent).openGraph?.images || [];
 
  return {
    title: product.title,
    openGraph: {
      images: ['/some-specific-page-image.jpg', ...previousImages],
    },
  };
}
 
export default function Page({ params, searchParams }: Props) {}


4 昇級後受到影響的套件


4.1 I18N 套件 ( 推薦 )

剛昇級完後就會發現相關的 i18n 套件無法使用,新版 useRouter 也不提供 locale 可以使用,試了好幾個 i18n 套件,發現這個套件最好用

相關文章

import { useLocale } from 'next-intl';


const locale = useLocale();


4.2 REACT QUERY 注入方式

相關文章


4.4 CONTEXT API 載入方式

相關文章


5 TURBOPACK( 仍在 BETA )

最後可以持續觀注的,Next.js 13 加了一個名為 Turbopack 的新的 JavaScript 打包工具,它被稱為 Webpack
的繼承者,Turbopack 由 Webpack 由 Rust 撰寫,號稱比原始 Webpack 快 700 倍(並且比 Vite 快 10 倍)。


6. 結論

無可否認,Next js 的更新速度令人驚訝,經常在我醒來之後就有了新的穩定版本,每次改版都會有點小陣痛,但大概都花個一至兩天就能昇級,也保留舊的寫法。

app route 改動的幅度有點大,且有點痛,但 app route出現,正式掀開 server side component 的序幕。


附錄 - 寫了一個 POWERSHELL 快速將 PAGE FOLDER 搬到 APP FOLDER

# Get a reference to all tsx files in the src\pages directory.
$files = Get-ChildItem -Path "src\pages" -Filter "*.tsx"


# For each file, create a new directory in src\app with the same name as the file (without extension),
# move the file to the new directory, rename it to page.tsx, and prepend 'use client;' to it.
foreach ($file in $files) {
    # Create new directory.
    $newDir = New-Item -Path "src\app\$($file.BaseName)\" -ItemType Directory


    # Move and rename the file.
    $newFile = Move-Item -Path $file.FullName -Destination "$($newDir.FullName)\page.tsx" -PassThru


    # Add 'use client;' to the beginning of the file.
    $content = Get-Content -Path $newFile.FullName
    $newContent = 'use client;' + "`n" + $content
    Set-Content -Path $newFile.FullName -Value $newContent
}


pause

--------------------------------------------------------------------------------


TAGS

ReactNextupgradeapp route


SHARE

--------------------------------------------------------------------------------





MARK KU


SOFTWARE DEVELOPER

擁有豐富網站開發經驗,直播系統、POS系統、電子商務、平台網站、SEO,專業的網站開發鐵三工程師。


EXPERTISE

前端(React)
後端(C#)
網路管理


SOCIAL MEDIA

facebook github website





RELATED POSTS


Frontend
程式碼標準 Coding Standard
Mark Ku
March 22, 2023
1 min
Frontend
NEXTJS 13 昇級筆記
Mark Ku
December 22, 2022
1 min
Frontend
Custom NextJS image loader with cloudflare
Mark Ku
November 11, 2022
1 min
Frontend
快速建立 Next js 開發環境筆記 ( ESlint + StyleLint + Prettier )
Mark Ku
July 29, 2022
1 min
Frontend
解決 Nextjs image loader 造成,docker image 肥大的問題
Mark Ku
July 26, 2022
1 min
Frontend
React 學習筆記 - 路由 ( Router ) - Part's 5
Mark Ku
July 23, 2022
1 min
© 2023, All Rights Reserved.


Quick Links

關於我

Legal Stuff

隱私權 Cookie策略

Social Media

facebook github website