เริ่มต้น › Next.js
เอกสาร/เริ่มต้น/Next.js

Next.js

หน้านี้สอนอะไร

route handler ของ Next.js ติดตั้งหน้า admin และ API อย่างไร และดึงเนื้อหาใน server component อย่างไร

ควรอ่านก่อน: เริ่มใช้งาน

@easy-cms/next รองรับ App Router ใน Next.js 15 ขึ้นไป

การตั้งค่า

npx create-easy-cms ทำขั้นตอนเหล่านี้ให้คุณ

1. ครอบ next.config.ts เพื่อให้ server build เก็บไฟล์ของหน้า admin, migration และไดรเวอร์ ฐานข้อมูลไว้ (โดยตั้งค่า serverExternalPackages และ outputFileTracingIncludes):

import type { NextConfig } from 'next'
import { withEasyCMS } from '@easy-cms/next/config'
 
const nextConfig: NextConfig = {}
export default withEasyCMS(nextConfig)

2. เพิ่ม route handler path ของ handler ต้องตรงกับ routes.api และ admin.path:

// app/api/cms/[[...path]]/route.ts
import { createRouteHandlers } from '@easy-cms/next'
import config from '@/easy-cms.config'
export const { GET, HEAD, POST, PATCH, PUT, DELETE, OPTIONS } = createRouteHandlers(config)
// app/admin/[[...path]]/route.ts
import { createAdminRouteHandlers } from '@easy-cms/next'
import config from '@/easy-cms.config'
export const { GET, HEAD } = createAdminRouteHandlers(config)

createRouteHandlers(config, options) รับตัวเลือกเหล่านี้ (RouteHandlerOptions ซึ่งเหมือน ApiHandlerOptions ทั้งสองถูก export):

ตัวเลือกค่าเริ่มต้น
basePathroutes.apiตำแหน่งที่ API อยู่
getClientIp—(request) => string | undefined: IP ของ client สำหรับจำกัดอัตราการเข้าสู่ระบบและ audit log ใช้ก่อน trustProxy
trustProxyfalseใช้ที่อยู่ตัวสุดท้ายใน X-Forwarded-For (ดูด้านล่าง) และเชื่อ X-Forwarded-Host ในการตรวจ origin ของ CSRF บน Vercel และ Netlify ไม่ต้องตั้ง

การอ่านเนื้อหา

import { connection } from 'next/server'
import { Suspense } from 'react'
import { getEasyCMS, getEasyCMSUser } from '@easy-cms/next'
import config from '@/easy-cms.config'
 
type Params = Promise<{ slug: string }>
 
export default function PostPage({ params }: { params: Params }) {
  return (
    <Suspense>
      <Post params={params} />
    </Suspense>
  )
}
 
async function Post({ params }: { params: Params }) {
  await connection() // อ่านใหม่ทุก request
  const { slug } = await params
  const cms = await getEasyCMS(config)
  const user = await getEasyCMSUser(config)
  const { docs } = await cms.find('posts', {
    where: { slug: { equals: slug } },
    overrideAccess: false,
    user,
    draft: user !== null,
    limit: 1,
  })
  // …
}

getEasyCMS(config) คืน instance เดียวต่อ server ซึ่งคงอยู่แม้มีการ hot reload ใช้ได้ ใน Server Components, Route Handlers และ Server Actions

สิ่งที่ควรรู้

  • ให้หน้าที่ดึงข้อมูลจาก CMS render ใหม่ทุก request: เรียก await connection() (จาก next/server) ใน async component ที่อยู่ใน <Suspense> แบบตัวอย่างข้างบน วิธีนี้ใช้ได้ทั้งตอนที่เปิดและไม่เปิด cacheComponents ใน next.config.ts แอปใหม่จาก create-next-app เปิดไว้ และในกรณีนั้นใช้ export const dynamic ไม่ได้ หรือจะ cache อย่างตั้งใจด้วย revalidation ก็ได้ มิฉะนั้น next build จะ prerender หน้าเหล่านั้นและ query ฐานข้อมูลตอน build
  • notFound() ที่อยู่ใน <Suspense> จะแสดงหน้า not-found พร้อม noindex แต่ status ยังเป็น 200 เพราะ Next.js เริ่มส่งหน้าไปแล้ว ส่วน generateMetadata อยู่นอก <Suspense> ได้
  • การจำกัดอัตราการเข้าสู่ระบบต้องรู้ IP ของ client บน Vercel และ Netlify หาได้เอง หลัง proxy อื่นที่เพิ่มที่อยู่ลงใน X-Forwarded-For ให้ใช้ createRouteHandlers(config, { trustProxy: true }) ระบบจะใช้ที่อยู่ตัวสุดท้าย (ตัวที่ proxy ของคุณเพิ่ม)
  • Next.js ตัดเครื่องหมาย slash ท้าย URL ออก หน้า admin จึงอยู่ที่ /admin (ไม่ใช่ /admin/)
  • ระหว่าง next dev การแก้ field หรือตัวเลือกจะโหลด CMS ใหม่ให้เอง แต่ถ้าแก้แค่โค้ดของ hook กฎสิทธิ์ หรือฟังก์ชันอื่นใน config ให้รีสตาร์ต dev server

ดูตัวอย่าง Next.js

ขั้นต่อไป