White(aegis4206)


NextJS

為解決React SEO問題的框架

環境安裝

npx create-next-app@latest 或 yarn create next-app
APP Router

App為根目錄,底下資料夾即為路由

App
|--post
    |--[postId]
        |--[...others]
// 使用[]代入參數

// 含有@無法透過url路由訪問
|--@component

// 可使用()作為Route Groups管理 利用()資料夾進行分類
// 其路由一樣透過 /auth /priority 訪問即可
|--(management)
    |--[auth]
    |--[priority]

router取出props代入參數

// url:/post/1/aa/bb?type=test
params: { 
    postId: "1",
    others: [ "aa", "bb" ] 
},
searchParams: { type: "test" }

新版next13以上預設為Server Component,不需要再去熟悉getServerSideProps、getStaticProps、getInitialProps
若需要切換為CSR,僅需在component上方加上以下程式碼即可

"use client"

使用<Image />引入外部圖片,需額外在next.config.js設定

next.config.js
module.exports = {
images: {
    remotePatterns: [
            {
                protocol: 'https',
                hostname: 'assets.example.com',
                port: '',
                pathname: '/account123/**',
            },
        ],
    },
}

Cache機制,若需要每次都重新fetch Data,需在參數項設定no-store,或者可使用ISR next參數項

fetch('https://random.imagecdn.app/v1/image?format=json', {
    cache:"no-store"

    // 或是設定next參數項,revalidate傳入刷新秒數
    next: {
        revalidate: 5,

    },
});

SSG應用,使用在資料不經常更動下,使用export fuNenction generateStaticParams

export async function generateStaticParams() {
    const posts = await fetch('https://.../posts').then((res) => res.json())
   
    // 透過map出來的所有id當成頁面的params參數(key)
    // 例如id = 1~10 , url:/post/1 /post/2 ...
    // 最後透過/post 代入各params.id依序做成SSR
    return posts.map((post) => ({
        id: post.id.toString(),
        })
    )
}
Styled Components

在CSR下使用可能造成CSS異步渲染的情況,可使用官方的解決方法,其做法為將全部CSS style rules先收集塞到Head裡面

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
    // 增加compiler
    compiler: {
        styledComponents: true,
    },
}

module.exports = nextConfig
lib/registry.tsx
'use client'
 
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
 
export default function StyledComponentsRegistry({
  children,
}: {
  children: React.ReactNode
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
 
  useServerInsertedHTML(() => {
    const styles = styledComponentsStyleSheet.getStyleElement()
    styledComponentsStyleSheet.instance.clearTag()
    return <>{styles}</>
  })
 
  if (typeof window !== 'undefined') return <>{children}</>
 
  return (
    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
      {children}
    </StyleSheetManager>
  )
}

使用方式類似狀態管理工具,需在外層在包覆一層

app/layout.tsx
import StyledComponentsRegistry from './lib/registry'
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <StyledComponentsRegistry>{children}</StyledComponentsRegistry>
      </body>
    </html>
  )
}

Copyright © 2025 white.