Skip to content

Core Concepts

ConceptDescriptionKey Features
Next.jsReact-based frameworkSSR/API routes, ไฟล์ app/, โหมด Hybrid rendering
Vercelเครื่องมือ build หลักHot Module Replacement, Build เร็ว, Plugin ecosystem
React Hooksรูปแบบการเขียน React componentsuseState() function, useContext(), Custom hooks
Next.js Routingการแชร์และการขยาย configurationExtend projects, Share components, Unified config
Automatic Importsการนำเข้าอัตโนมัติComponents, Hooks, React APIs
File-based Routingระบบ routing จากโครงสร้างไฟล์app/ directory, Dynamic routes, Route middleware

Key Features

คุณสมบัติรายละเอียดตัวอย่าง
File-based Routingสร้างเส้นทางอัตโนมัติจากโครงสร้างไฟล์app/about/page.tsx/about
Server-side Renderingการแสดงผลฝั่งเซิร์ฟเวอร์ใช้ fetch() สำหรับดึงข้อมูลใน SSR
Static Site Generationการสร้างเว็บไซต์แบบสแตติกคำสั่ง next build และ next export
Automatic Importsนำเข้า components/hooks อัตโนมัติใช้ useRouter() โดยไม่ต้อง import
App Directoryระบบโมดูลสำหรับเพิ่มความสามารถapp/, pages/, components/
Hybrid Renderingผสมผสาน SSR, SSG และ CSR ในแอปเดียวexport const dynamic = 'force-static'
DevToolsเครื่องมือพัฒนาที่มีในตัวReact Developer Tools
API Routesสร้าง API endpoints ฝั่งเซิร์ฟเวอร์ไฟล์ใน app/api/ จะกลายเป็นเส้นทาง API
Middlewareการจัดการความปลอดภัยของเส้นทางไฟล์ middleware.ts ใน root directory
State ManagementการจัดการสถานะuseState, useReducer, หรือ libraries ภายนอก

Getting Started

  1. Installation

ติดตั้ง Next.js และ dependencies ที่จำเป็นด้วย package manager ที่คุณเลือก:

bash
npx create-next-app@latest
npm run dev
bash
pnpm create next-app
pnpm run dev
bash
yarn create next-app
yarn dev
bash
bun create next-app
bun run dev
  1. Run Development Server

เริ่มต้น development server สำหรับการพัฒนาแบบ real-time:

bash
npm run dev
  1. Build for Production

สร้างไฟล์สำหรับ production ที่ optimize แล้ว:

bash
npm run build

Configuration

Next.js ใช้ไฟล์ next.config.js สำหรับการกำหนดค่า ตัวเลือกหลัก:

ตัวเลือกคำอธิบายตัวอย่าง
reactStrictModeเปิดใช้งาน React Strict Modetrue
outputโหมดการ export (static/standalone)'standalone'
imagesการตั้งค่าการปรับรูปภาพ{ domains: [...] }
envตัวแปรสภาพแวดล้อม{ API_URL: process.env.API_URL }
experimentalคุณสมบัติทดลอง{ appDir: true }
compilerตัวเลือกคอมไพลเลอร์{ styledComponents: true }

Example Config

js
// next.config.js
module.exports = {
  reactStrictMode: true,
  output: 'standalone',
  images: {
    domains: ['example.com'],
  },
  env: {
    API_URL: process.env.API_URL,
  },
  experimental: {
    appDir: true,
  },
  compiler: {
    styledComponents: true,
  },
}

TypeScript Support

For TypeScript, create a next-env.d.ts file:

ts
/// <reference types="next" />
/// <reference types="next/image-types/global" />

Directory Structure

โครงสร้างไดเรกทอรีมาตรฐานของ Next.js:

  • app/: เก็บ page components และ layouts (App Router)
  • pages/: สร้าง routes อัตโนมัติจากไฟล์ (Pages Router)
  • components/: เก็บ reusable components
  • public/: เก็บ static files
  • styles/: เก็บ global styles
my-next-app/
├── app/
│   ├── layout.tsx       # Root layout
│   ├── page.tsx        # Home page
│   └── about/
│       └── page.tsx    # About page
├── components/
│   ├── Header.tsx
│   └── Footer.tsx
├── pages/
│   ├── _app.tsx        # Custom App component
│   └── api/
│       └── hello.ts    # API route
├── public/
│   └── favicon.ico
├── styles/
│   └── globals.css
└── next.config.js      # Next.js configuration

Deployment

Deployment Targets

TargetCommandConfigOutput Directory
VercelAutomaticNone neededN/A
Node.jsnext build + next startoutput: 'standalone'.next
Staticnext build + next exportoutput: 'export'out/
Dockerdocker buildDockerfileImage
EdgeAutomaticruntime: 'edge'N/A

Implementation Examples

bash
# Just push to connected Git repository
# Automatic deployments configured in Vercel
bash
npm run build
npm run export
# Outputs to out/ directory
dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

EXPOSE 3000
CMD ["npm", "start"]
js
// pages/api/hello.js
export const config = {
  runtime: 'edge'
}

export default function handler(request) {
  return new Response('Hello from edge!')
}

Pages and Routing

Next.js สร้างเส้นทางอัตโนมัติจากโครงสร้างไดเรกทอรี pages/

ConceptDescriptionExample
Basic Routeเส้นทางพื้นฐานจากไฟล์pages/index.tsx/
Dynamic Routeเส้นทางแบบไดนามิกด้วยพารามิเตอร์pages/users/[id].tsx/users/123
Nested Routeเส้นทางแบบซ้อนจากโฟลเดอร์pages/products/index.tsx/products
jsx
// pages/index.tsx
export default function HomePage() {
  return <div>Home Page</div>
}
jsx
// pages/users/[id].tsx
export default function UserPage({ params }) {
  return <div>User ID: {params.id}</div>
}
jsx
// pages/about.tsx
export default function AboutPage() {
  return <div>หน้าเกี่ยวกับเรา</div>
}

Layer

คุณสมบัติคำอธิบายการกำหนดค่า
Extendsแชร์ components/confignext.config.js
Presetsการตั้งค่าล่วงหน้าextends: ['@next/ui']
Modulesเพิ่มความสามารถmodules: []
js
// next.config.js
module.exports = {
  extends: ['github:owner/repo']
}
js
// next.config.js
module.exports = {
  modules: ['@next/image']
}
js
// my-layer/next.config.js
module.exports = {
  components: {
    dirs: ['~/components']
  }
}

View

คุณสมบัติคำอธิบายตัวอย่าง
Templatesโครงสร้างเลย์เอาต์app/layout.tsx
Componentsองค์ประกอบ UI ที่นำกลับมาใช้ใหม่ได้components/
Pagesองค์ประกอบเส้นทางpages/
Dynamic Importsการโหลดแบบล่าช้าimport('~/components/HeavyComponent')
jsx
// app/layout.tsx
export default function Layout({ children }) {
  return (
    <div>
      <AppHeader />
      {children}
      <AppFooter />
    </div>
  )
}
jsx
// pages/about.tsx
import dynamic from 'next/dynamic'

const Component = dynamic(() => import('~/components/HeavyComponent'))

export default function AboutPage() {
  return <Component />
}
js
// next.config.js
module.exports = {
  app: {
    pageTransition: { name: 'page', mode: 'out-in' }
  }
}

Styling

MethodDescriptionConfiguration
CSS Modulesสไตล์แบบเฉพาะที่*.module.css
Sassภาษา CSS ขั้นสูงnpm install -D sass
CSS-in-JSสไตล์แบบฝั่งไคลเอนต์npm install -D styled-components
css
/* components/Button.module.css */
.button {
  background: #00dc82;
}
jsx
// pages/about.tsx
import styles from '../styles/about.module.scss'

export default function AboutPage() {
  return <div className={styles.container}>Content</div>
}
jsx
// components/Button.tsx
import styled from 'styled-components'

const Button = styled.button`
  background: #00dc82;
`

export default Button

SEO and Meta

Next.js มี utilities สำหรับจัดการ SEO และ meta tags:

  • Head component: สำหรับตั้งค่า meta tags พื้นฐาน
  • next/head: สำหรับ meta tags ของโซเชียลมีเดีย
  • next-sitemap: สร้าง sitemap.xml อัตโนมัติ
  • Meta tags จะถูก inject ใน SSR/SSG mode
เทคนิคคำอธิบายการนำไปใช้
Basic Metaเมตาแท็กพื้นฐานSEO ทั่วไป
Social MetaOpenGraph/Twitter cardsการแชร์บนโซเชียล
Sitemapการสร้างแผนผังเว็บไซต์การจัดทำดัชนีโดยเสิร์ชเอนจิน
jsx
// pages/about.tsx
import Head from 'next/head'

export default function AboutPage() {
  return (
    <div>
      <Head>
        <title>หน้าแรก</title>
        <meta name="description" content="คำอธิบายเว็บไซต์" />
        <meta name="keywords" content="next, react, javascript" />
      </Head>
      <div>หน้าเกี่ยวกับเรา</div>
    </div>
  )
}
jsx
// pages/about.tsx
import Head from 'next/head'

export default function AboutPage() {
  return (
    <div>
      <Head>
        <title>หน้าแรก | เว็บไซต์ของฉัน</title>
        <meta property="og:title" content="หน้าแรก | เว็บไซต์ของฉัน" />
        <meta property="og:description" content="คำอธิบายเว็บไซต์สำหรับ social media" />
        <meta property="og:image" content="https://example.com/image.jpg" />
      </Head>
      <div>หน้าเกี่ยวกับเรา</div>
    </div>
  )
}
js
// next.config.js
module.exports = {
  sitemap: {
    hostname: 'https://example.com',
    routes: ['/', '/about']
  }
}

Data Fetching

วิธีคำอธิบายเหมาะสำหรับ
getStaticPropsการดึงข้อมูลสำหรับ SSGการเรนเดอร์แบบสแตติก
getServerSidePropsการดึงข้อมูลสำหรับ SSRการเรนเดอร์แบบเซิร์ฟเวอร์
fetchการร้องขอ API แบบแมนนวลการเรียก API แบบแมนนวล
jsx
// pages/about.tsx
export const getStaticProps = async () => {
  const data = await fetch('https://api.example.com/data')
  return {
    props: {
      data: await data.json()
    }
  }
}
jsx
// pages/about.tsx
export const getServerSideProps = async () => {
  const data = await fetch('https://api.example.com/data')
  return {
    props: {
      data: await data.json()
    }
  }
}
jsx
// pages/about.tsx
import fetch from 'isomorphic-unfetch'

export default function AboutPage() {
  const [data, setData] = useState(null)

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data))
  }, [])

  return <div>Data: {data}</div>
}

State Management

Next.js มีวิธีการจัดการ state หลายแบบ:

วิธีการคำอธิบายเมื่อไหร่ควรใช้
React HooksuseState, useReducerสถานะภายในคอมโพเนนต์
Context APIcreateContext, useContextสถานะที่แชร์ระหว่างคอมโพเนนต์
Server Componentsดึงข้อมูลจากเซิร์ฟเวอร์ข้อมูลที่ไม่เปลี่ยนแปลงบ่อย
URL Search Paramsเก็บสถานะใน URLการกรองข้อมูล, การแบ่งหน้า
External LibrariesZustand, Reduxสถานะระดับแอปพลิเคชันที่ซับซ้อน
jsx
// components/Counter.js
import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}
jsx
// context/ThemeContext.js
import { createContext, useContext } from 'react'

const ThemeContext = createContext('light')

export function ThemeProvider({ children }) {
  return (
    <ThemeContext.Provider value="dark">
      {children}
    </ThemeContext.Provider>
  )
}

export function useTheme() {
  return useContext(ThemeContext)
}
jsx
// pages/products.js
import { useRouter } from 'next/router'

export default function Products() {
  const router = useRouter()
  const { page = '1' } = router.query

  return (
    <div>
      <p>Current Page: {page}</p>
      <button onClick={() => router.push(`?page=${Number(page) + 1}`)}>
        Next Page
      </button>
    </div>
  )
}

Environment Variables

การจัดการ environment variables ใน Next.js:

  • ตัวแปรสาธารณะ (public): เข้าถึงได้ทั้งฝั่ง client และ server
  • ตัวแปรส่วนตัว (private): เข้าถึงได้เฉพาะฝั่ง server
  • runtimeConfig: สำหรับการกำหนดค่าที่สามารถ override ได้
  • ควรเก็บค่าลับในไฟล์ .env ที่ไม่ถูก commit
ประเภทตัวแปรการใช้งานตัวอย่าง
Publicเข้าถึงได้ฝั่งไคลเอนต์NEXT_PUBLIC_API_BASE
Privateเฉพาะฝั่งเซิร์ฟเวอร์DATABASE_URL
Runtime Configการเข้าถึงแบบ type-saferuntimeConfig
sh
# Public (client-side)
NEXT_PUBLIC_API_BASE=https://api.example.com

# Private (server-only)
DATABASE_URL=postgres://user:pass@localhost:5432/db
js
// next.config.js
module.exports = {
  runtimeConfig: {
    apiSecret: '', // Can be overridden by NEXT_API_SECRET
    public: {
      apiBase: '/api' // NEXT_PUBLIC_API_BASE
    }
  }
}
jsx
// pages/about.tsx
import { useRuntimeConfig } from 'next/config'

export default function AboutPage() {
  const config = useRuntimeConfig()

  // Client-side
  const apiBase = config.public.apiBase

  // Server-side (API routes)
  // const apiSecret = config.apiSecret
}

Optimization

Next.js provides built-in optimizations:

TechniqueDescriptionImplementation
Image OptimizationAutomatic resizing/formattingnext/image component
Font OptimizationAutomatic font subsettingnext/font
Script OptimizationAsync/defer script loadingnext/script
Lazy LoadingOn-demand component loadingdynamic() import
Code SplittingAutomatic per-route splittingBuilt-in
ISRIncremental Static Regenerationrevalidate in getStaticProps
jsx
import Image from 'next/image'

export default function Avatar() {
  return (
    <Image
      src="/profile.jpg"
      alt="Profile"
      width={500}
      height={500}
      priority // Preload important images
    />
  )
}
jsx
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export default function MyApp() {
  return (
    <div className={inter.className}>
      My styled text
    </div>
  )
}
jsx
import dynamic from 'next/dynamic'

const HeavyComponent = dynamic(
  () => import('../components/HeavyComponent'),
  { 
    loading: () => <p>Loading...</p>,
    ssr: false // Disable server-side render
  }
)

export default function Page() {
  return <HeavyComponent />
}

Best Practices

โครงสร้างโปรเจค

องค์ประกอบตำแหน่งที่เก็บตัวอย่าง
หน้าเว็บหลักapp/app/page.tsx
คอมโพเนนต์components/components/Button.tsx
ฮุคhooks/hooks/useAuth.ts
ยูทิลิตี้utils/ หรือ lib/utils/api.ts

ประสิทธิภาพ

เทคนิคคำอธิบายตัวอย่าง
การปรับรูปภาพใช้ next/imageimport Image from 'next/image'
Static Generationใช้ getStaticPropsเหมาะสำหรับข้อมูลที่ไม่เปลี่ยนแปลงบ่อย
ISRอัปเดตข้อมูลแบบค่อยเป็นค่อยไปrevalidate: 60 (วินาที)
Code Splittingโหลดโค้ดเมื่อจำเป็นdynamic() import
jsx
// pages/products.js
export async function getStaticProps() {
  const res = await fetch('https://.../products')
  const products = await res.json()

  return {
    props: { products },
    revalidate: 60 // ISR: อัปเดตทุก 60 วินาที
  }
}
jsx
import dynamic from 'next/dynamic'

const HeavyComponent = dynamic(
  () => import('../components/HeavyComponent'),
  { loading: () => <p>Loading...</p> }
)

ความปลอดภัย

ข้อควรระวังวิธีป้องกัน
ข้อมูลผู้ใช้ตรวจสอบข้อมูลก่อนใช้งาน
คีย์ลับใช้ environment variables
CORSกำหนดนโยบายที่เหมาะสม
XSSทำความสะอาดข้อมูลก่อนแสดงผล

การพัฒนา

เครื่องมือการใช้งาน
TypeScriptสำหรับตรวจสอบประเภทข้อมูล
ESLintตรวจสอบคุณภาพโค้ด
Prettierจัดรูปแบบโค้ดอัตโนมัติ
Jestทดสอบหน่วยงาน
Playwrightทดสอบ End-to-End

Last updated: