วันศุกร์ที่ 7 มีนาคม พ.ศ. 2568

ใช้ Prisma เป็น ORM กับ Next.js ให้ชีวิตง่ายขึ้น!

ถ้าคุณกำลังทำ Next.js และต้องการให้เว็บของคุณเชื่อมต่อกับฐานข้อมูล อย่างง่ายและมีประสิทธิภาพ คุณคงเคยปวดหัวกับการเขียน SQL Query ตรง ๆ หรือการจัดการ Migrations ใช่ไหม? 🤯

วันนี้เราจะมาแนะนำ Prisma 🏆 ซึ่งเป็น ORM (Object-Relational Mapping) ที่ทำให้การจัดการฐานข้อมูลกับ Next.js เป็นเรื่องง่าย อ่านโค้ดสวยสะอาดตา และใช้งานได้ทั้ง TypeScript และ JavaScript


🎯 Prisma คืออะไร?

Prisma เป็น ORM ที่ช่วยให้เราทำงานกับฐานข้อมูล ง่ายขึ้น แทนที่เราจะต้องเขียน SQL ตรง ๆ เราสามารถใช้ Prisma Client เพื่อดึงหรือบันทึกข้อมูลได้สะดวกขึ้น

🔥 จุดเด่นของ Prisma

✅ Type-safe → ใช้กับ TypeScript ได้เต็มที่
✅ Readable Code → โค้ดอ่านง่ายขึ้นเยอะ
✅ Auto Migrations → จัดการโครงสร้างฐานข้อมูลได้ง่าย
✅ รองรับหลาย Database → PostgreSQL, MySQL, SQLite, MongoDB, etc.
✅ ทำงานร่วมกับ Next.js ได้ดีมาก

🛠 ติดตั้ง Prisma ใน Next.js

ก่อนอื่น เราต้องมี Next.js Project ก่อน ถ้ายังไม่มีให้สร้างด้วยคำสั่งนี้

npx create-next-app my-next-app
cd my-next-app

จากนั้น ติดตั้ง Prisma และ PostgreSQL Client (หรือ Database อื่น ๆ ที่คุณใช้)

npm install @prisma/client @prisma/cli pg

🔹 ตั้งค่า Database Connection

Prisma ใช้ไฟล์ .env เพื่อเก็บ Database URL

🔧 เปิดไฟล์ .env แล้วเพิ่มค่าต่อไปนี้

DATABASE_URL=postgresql://username:password@localhost:5432/mydatabase

📌 เปลี่ยน username, password, และ mydatabase ให้ตรงกับ Database ของคุณ


🔹 ตั้งค่า Prisma Schema

สร้างโฟลเดอร์ prisma/ และไฟล์ schema.prisma

npx prisma init

ตอนนี้โครงสร้างโปรเจกต์ของคุณควรเป็นแบบนี้

/my-next-app
 ├── /prisma
 │   └── schema.prisma
 ├── /pages
 ├── /components
 ├── .env
 ├── package.json

🔧 แก้ไขไฟล์ prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String  @unique
}

🔹 สร้าง Database Migration

ใช้คำสั่งนี้เพื่อให้ Prisma สร้างตารางใน Database ตาม Schema ที่เรากำหนด

npx prisma migrate dev --name init

📌 คำสั่งนี้จะสร้างตาราง User ในฐานข้อมูลของคุณ


🔹 ใช้ Prisma ใน API Routes ของ Next.js

💡 เราจะลองสร้าง API ที่จัดการ Users โดยใช้ Prisma

📌 อ่านข้อมูล Users (/pages/api/users.js)

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const users = await prisma.user.findMany()
    res.json(users)
  }
}

✅ ตอนนี้เรามี API ที่สามารถดึง Users ได้แล้ว

📌 เพิ่ม User ใหม่ (/pages/api/users.js)

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { name, email } = req.body
    const newUser = await prisma.user.create({
      data: { name, email }
    })
    res.json(newUser)
  }
}

✅ ตอนนี้เราสามารถเพิ่ม Users ได้แล้ว

📌 แก้ไขข้อมูล User (/pages/api/users/[id].js)

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
  const { id } = req.query

  if (req.method === 'PUT') {
    const { name, email } = req.body
    const updatedUser = await prisma.user.update({
      where: { id: Number(id) },
      data: { name, email }
    })
    res.json(updatedUser)
  }
}

✅ ตอนนี้เราสามารถอัปเดตข้อมูล Users ได้แล้ว

📌 ลบ User (/pages/api/users/[id].js)

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
  const { id } = req.query

  if (req.method === 'DELETE') {
    await prisma.user.delete({
      where: { id: Number(id) }
    })
    res.json({ message: 'User deleted' })
  }
}

✅ ตอนนี้เราสามารถลบ Users ได้แล้ว

🎯 ทำไมต้องใช้ Prisma กับ Next.js?

ฟีเจอร์ Prisma SQL Query ตรง ๆ
ใช้งานง่าย ✅ ❌
อ่านโค้ดง่าย ✅ ❌
รองรับ TypeScript ✅ ❌
มีระบบ Migrations ✅ ❌
จัดการ Query Complex ได้ง่าย ✅ ❌

📌 ถ้าคุณต้องการ ORM ที่ใช้งานง่ายและรองรับ TypeScript ดี → Prisma คือคำตอบ!


🎯 สรุป

✅ Prisma เป็น ORM ที่ช่วยให้คุณทำงานกับ Database ใน Next.js ได้ง่ายขึ้น
✅ รองรับ PostgreSQL, MySQL, SQLite, MongoDB
✅ ใช้ร่วมกับ Next.js API Routes ได้ดี
✅ ใช้งานง่าย อ่านโค้ดสบายตา

วันพฤหัสบดีที่ 6 มีนาคม พ.ศ. 2568

การเชื่อมต่อ PostgreSQL กับ Next.js: ทำเว็บให้มี Database กันเถอะ!

ถ้าคุณกำลังทำเว็บด้วย Next.js แล้วอยากให้มัน เก็บข้อมูล ได้จริง ๆ ไม่ใช่แค่โชว์ข้อมูลสวย ๆ การเชื่อมต่อกับ PostgreSQL เป็นหนึ่งในทางเลือกที่ดีมาก! 🔥

PostgreSQL (หรือที่เรียกสั้น ๆ ว่า Postgres) เป็นฐานข้อมูลเชิงสัมพันธ์ (Relational Database) ที่ เร็ว, เสถียร, และรองรับข้อมูลขนาดใหญ่ ได้ดี มีฟีเจอร์เด็ด ๆ อย่าง JSONB, Indexing, Full-text search และอื่น ๆ อีกเพียบ! 💾

ในบทความนี้ เราจะมาดูกันว่า จะเชื่อมต่อ PostgreSQL กับ Next.js ยังไง ใช้ Prisma, pg, หรือ Drizzle อันไหนเหมาะกับงานแบบไหน และทำยังไงให้โค้ดอ่านง่ายและดูแลต่อได้ง่าย

🎯 PostgreSQL + Next.js ใช้ทำอะไรได้บ้าง?

ถ้าคุณสร้างเว็บที่ต้องการ บันทึกและดึงข้อมูล จากฐานข้อมูล เช่น

✅ เว็บบล็อก → บันทึกและเรียกดูบทความ
✅ เว็บร้านค้า → จัดเก็บสินค้าและคำสั่งซื้อ
✅ ระบบล็อกอิน → เก็บข้อมูลผู้ใช้และการยืนยันตัวตน
✅ เว็บแอปที่ต้องใช้ข้อมูลจริง → เช่น Dashboard, CRM, หรือระบบจอง

การใช้ PostgreSQL เป็นทางเลือกที่ดี เพราะมันรองรับ โครงสร้างข้อมูลที่ซับซ้อน และ ขยายขนาดได้ง่าย 🚀

🛠 วิธีเชื่อมต่อ PostgreSQL กับ Next.js

การเชื่อมต่อ PostgreSQL กับ Next.js ทำได้หลายวิธี เช่น

วิธี ใช้เมื่อ ตัวอย่างเครื่องมือ
ใช้ Prisma ต้องการ ORM ที่ใช้งานง่ายและโค้ดอ่านสวย Prisma
ใช้ pg (node-postgres) ต้องการทำงานกับ SQL โดยตรง pg (node-postgres)
ใช้ Drizzle ORM ต้องการ ORM ที่เบาและเร็ว Drizzle
ใช้ Direct SQL (raw queries) ต้องการประสิทธิภาพสูงสุด SQL Queries ตรง ๆ

🔹 1. เชื่อมต่อ PostgreSQL ด้วย Prisma (ง่ายสุด!)

Prisma เป็น ORM ที่ได้รับความนิยมมาก เพราะมันช่วยให้เราสามารถเขียนโค้ด TypeScript ที่อ่านง่าย และลดปัญหาการจัดการฐานข้อมูล

🏗 ติดตั้ง Prisma และ PostgreSQL Client

npm install @prisma/client @prisma/cli pg

📝 ตั้งค่า .env ให้เชื่อมต่อ PostgreSQL

DATABASE_URL=postgresql://username:password@localhost:5432/mydatabase

🛠 ตั้งค่า Prisma Schema

สร้างไฟล์ prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String  @unique
}

🚀 สร้างตารางใน Database

npx prisma migrate dev --name init

📌 ใช้ Prisma ใน API Routes (/pages/api/users.js)

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const users = await prisma.user.findMany()
    res.json(users)
  } else if (req.method === 'POST') {
    const { name, email } = req.body
    const newUser = await prisma.user.create({
      data: { name, email }
    })
    res.json(newUser)
  }
}

✅ ทำไมต้องใช้ Prisma?

✔ ใช้ง่ายและอ่านง่าย
✔ มี Type Safety (ใช้กับ TypeScript ได้ดี)
✔ จัดการ Database Migrations ได้สะดวก

🔹 2. เชื่อมต่อ PostgreSQL ด้วย pg (ทำงานกับ SQL ตรง ๆ)

ถ้าคุณต้องการ เขียน SQL เองโดยตรง และต้องการความยืดหยุ่นสูง pg (node-postgres) เป็นตัวเลือกที่ดี

🏗 ติดตั้ง pg

npm install pg

📝 เชื่อมต่อ PostgreSQL (lib/db.js)

import { Pool } from 'pg'

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
})

export async function query(text, params) {
  const res = await pool.query(text, params)
  return res.rows
}

📌 ใช้ pg ใน API Routes (/pages/api/users.js)

import { query } from '../../lib/db'

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const users = await query('SELECT * FROM users', [])
    res.json(users)
  } else if (req.method === 'POST') {
    const { name, email } = req.body
    const newUser = await query(
      'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
      [name, email]
    )
    res.json(newUser)
  }
}

✅ ทำไมต้องใช้ pg?

✔ ควบคุม SQL Query ได้เต็มที่
✔ เบาและเร็วกว่า ORM
✔ รองรับ Transactions และ Connection Pooling


🔹 3. ใช้ Drizzle ORM (ทางเลือกใหม่ เบาและเร็ว!)

ถ้าคุณต้องการ ORM ที่ เบาและเร็วกว่า Prisma Drizzle ORM เป็นตัวเลือกที่น่าสนใจ

🏗 ติดตั้ง Drizzle ORM

npm install drizzle-orm pg

📝 สร้าง Connection (lib/db.ts)

import { drizzle } from 'drizzle-orm/node-postgres'
import { Pool } from 'pg'

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
})

export const db = drizzle(pool)

📌 ใช้ Drizzle ใน API Routes (/pages/api/users.ts)

import { db } from '../../lib/db'

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const users = await db.select().from('users')
    res.json(users)
  }
}

✅ ทำไมต้องใช้ Drizzle?

✔ เร็วกว่า Prisma
✔ ใช้ TypeScript ได้ดี
✔ อ่านง่ายและไม่ต้องใช้ Migrations ใหญ่ ๆ

🎯 สรุป

วิธี ใช้เมื่อ เครื่องมือที่ใช้
Prisma ต้องการ ORM ที่ใช้งานง่าย Prisma
pg (node-postgres) ต้องการเขียน SQL เอง pg
Drizzle ORM ต้องการ ORM ที่เบาและเร็ว Drizzle


🔹 ถ้าคุณ ชอบ ORM และอยากให้โค้ดดูสวย ๆ → ใช้ Prisma
🔹 ถ้าคุณ ต้องการความเร็วและควบคุม SQL เอง → ใช้ pg
🔹 ถ้าคุณ อยากได้ ORM ที่เบาและเร็วกว่า Prisma → ใช้ Drizzle

วันพุธที่ 5 มีนาคม พ.ศ. 2568

การแคชข้อมูลใน Next.js: โหลดเร็ว ประหยัดทรัพยากร ทำยังไง?

ถ้าอยากให้เว็บโหลดเร็ว แคช (Cache) คือสิ่งที่ต้องรู้! แคชช่วยลดการเรียก API ซ้ำ ๆ ประหยัดเวลา ประหยัดเซิร์ฟเวอร์ และทำให้ผู้ใช้รู้สึกว่าเว็บเร็วขึ้นมาก 🚀

ใน Next.js เรามีหลายวิธีในการแคชข้อมูล ตั้งแต่ Static Generation (SSG), Server-side Rendering (SSR), Client-side caching (SWR) ไปจนถึง Edge Caching วันนี้เราจะมาดูกันว่าแต่ละแบบใช้เมื่อไหร่ และทำให้เว็บเร็วขึ้นได้ยังไง!

🔥 ทำไมต้องแคชข้อมูล?

ลองนึกภาพว่าเว็บของคุณต้องโหลด สินค้าล่าสุด จาก API ทุกครั้งที่มีคนเข้าเว็บ … 🤯

  • ถ้าคนเข้า 100 คน = API ถูกเรียก 100 ครั้ง
  • ถ้า API ช้า? เว็บช้าไปด้วย
  • ถ้า API มีค่าใช้จ่าย? ยิ่งแพงขึ้นเรื่อย ๆ

แต่ถ้าเราสามารถเก็บข้อมูลไว้ชั่วคราว ไม่ต้องเรียก API ตลอดเวลา เว็บจะเร็วขึ้น ประหยัดทรัพยากร และลดโหลดเซิร์ฟเวอร์

🛠 วิธีการแคชใน Next.js

Next.js รองรับการแคชหลายแบบขึ้นอยู่กับว่า ข้อมูลของคุณเปลี่ยนบ่อยแค่ไหน

วิธีแคช ใช้เมื่อ ตัวอย่าง
Static Generation (SSG) ข้อมูลไม่ค่อยเปลี่ยน หน้า About, รายการสินค้า
Incremental Static Regeneration (ISR) ข้อมูลเปลี่ยนเป็นช่วง ๆ บทความข่าว, ราคา Bitcoin
Server-side Rendering (SSR) ข้อมูลต้องสดใหม่ทุกครั้ง ข้อมูลผู้ใช้, หน้าแดชบอร์ด
Client-side Fetching (SWR, React Query) ข้อมูลเปลี่ยนบ่อยแบบเรียลไทม์ Notification, Dashboard
Edge Caching ต้องการโหลดเร็วสุด ๆ Content ที่แจกจ่ายไปทั่วโลก (CDN)


🏗 1. แคชข้อมูลด้วย Static Generation (SSG)

ถ้าข้อมูลไม่เปลี่ยนบ่อย SSG เป็นวิธีที่ดีที่สุด เพราะ Next.js จะ ดึงข้อมูลมาตอน Build แล้วเสิร์ฟเป็นไฟล์ HTML ทำให้โหลดเร็วสุด ๆ

🔹 ตัวอย่าง SSG

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/products')
  const products = await res.json()

  return { props: { products } }
}

export default function ProductsPage({ products }) {
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSG

  • โหลดเร็วมาก เพราะเป็นไฟล์ HTML ธรรมดา
  • ลดโหลดเซิร์ฟเวอร์
  • เหมาะกับข้อมูลที่ไม่เปลี่ยนบ่อย เช่น บทความ หรือ รายการสินค้า

❌ ข้อเสีย

  • ถ้าข้อมูลเปลี่ยน จะไม่อัปเดตจนกว่าจะ Build ใหม่


🔄 2. อัปเดต Static Page ด้วย ISR (Incremental Static Regeneration)

ถ้าอยากใช้ SSG แต่ให้ข้อมูลอัปเดตเป็นช่วง ๆ เราสามารถใช้ revalidate เพื่อให้ Next.js รีเฟรชข้อมูลอัตโนมัติ

🔹 ตัวอย่าง ISR (รีเฟรชข้อมูลทุก 60 วินาที)

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/news')
  const news = await res.json()

  return { props: { news }, revalidate: 60 } // รีเฟรชทุก 60 วินาที
}

✅ ข้อดีของ ISR

  • โหลดเร็วเหมือน SSG
  • ข้อมูลอัปเดตได้เอง ไม่ต้อง Deploy ใหม่


⚡ 3. โหลดข้อมูลฝั่งเซิร์ฟเวอร์ (SSR)

ถ้าข้อมูลต้องอัปเดตทุกครั้งที่มีคนเข้าหน้า SSR (Server-side Rendering) คือทางเลือกที่ดี

🔹 ตัวอย่าง SSR

export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/user')
  const user = await res.json()

  return { props: { user } }
}

✅ ข้อดีของ SSR

  • ข้อมูลสดใหม่เสมอ
  • เหมาะกับข้อมูลผู้ใช้ หรือแดชบอร์ด

❌ ข้อเสีย

  • ช้ากว่า SSG และ ISR เพราะต้องรอโหลดทุกครั้ง


🌀 4. แคชข้อมูลฝั่ง Client ด้วย SWR

ถ้าต้องการให้ข้อมูล อัปเดตอัตโนมัติแบบเรียลไทม์ ใช้ SWR (Stale-While-Revalidate) เป็นตัวเลือกที่ดี

🔹 ตัวอย่างการใช้ SWR

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then(res => res.json())

export default function Dashboard() {
  const { data, error } = useSWR('/api/dashboard', fetcher, { refreshInterval: 5000 })

  if (error) return <p>เกิดข้อผิดพลาด</p>
  if (!data) return <p>กำลังโหลด...</p>

  return <div>จำนวนผู้ใช้ตอนนี้: {data.users}</div>
}

✅ ข้อดีของ SWR

  • โหลดเร็วเพราะดึงจากแคชก่อน
  • อัปเดตข้อมูลอัตโนมัติ

❌ ข้อเสีย

  • ใช้ได้เฉพาะฝั่ง Client


🌍 5. ใช้ Edge Caching เพื่อโหลดเร็วสุด ๆ

ถ้าอยากให้ Response ถูกแคชทั่วโลก (CDN) Next.js มีฟีเจอร์ Middleware + Edge Functions

🔹 ตัวอย่าง Middleware Caching

import { NextResponse } from 'next/server'

export function middleware(req) {
  const response = NextResponse.next()
  response.headers.set('Cache-Control', 's-maxage=60, stale-while-revalidate')
  return response
}

✅ เหมาะกับ

  •     โหลดเร็วสุด ๆ สำหรับ Static Content
  •     ใช้ร่วมกับ CDN เช่น Vercel, Cloudflare


🔥 สรุป: ควรใช้แคชแบบไหน?

วิธีแคช ใช้เมื่อ
SSG ข้อมูลไม่เปลี่ยนบ่อย (โหลดเร็วมาก)
ISR ข้อมูลเปลี่ยนเป็นช่วง ๆ (อัปเดตอัตโนมัติ)
SSR ข้อมูลต้องสดใหม่ทุกครั้ง
SWR อัปเดตข้อมูลอัตโนมัติฝั่ง Client
Edge Caching โหลดเร็วสุด ๆ ทั่วโลก

✅ ใช้ SSG หรือ ISR ถ้าเป็นไปได้ เพราะเร็วและลดโหลดเซิร์ฟเวอร์
✅ ใช้ SSR เมื่อข้อมูลต้องอัปเดตเสมอ
✅ ใช้ SWR ถ้าเป็นข้อมูลที่ต้องอัปเดตเรียลไทม์

วันอังคารที่ 4 มีนาคม พ.ศ. 2568

การใช้งาน Middleware ใน Next.js

ถ้าพูดถึง Middleware หลายคนอาจนึกถึง Express.js ที่ใช้ตรวจสอบ Request ก่อนส่งไปยัง Handler แต่รู้ไหมว่า Next.js ก็มี Middleware เป็นของตัวเอง!

Middleware ใน Next.js ช่วยให้เราสามารถ ควบคุมการเข้าถึงหน้าเว็บ, ตรวจสอบสิทธิ์ (Authentication), Redirect, และ Modify Request/Response ได้ก่อนที่ผู้ใช้จะเข้าถึงหน้าเว็บจริง ๆ

ในบทความนี้ เราจะมาดูกันว่า Middleware ใน Next.js คืออะไร ใช้งานยังไง และเราสามารถนำไปใช้ทำอะไรได้บ้าง 🛠️🚀

🔥 Middleware ใน Next.js คืออะไร?

Middleware คือ โค้ดที่ทำงานอยู่ระหว่าง Request และ Response หรือพูดง่าย ๆ ก็คือ มันช่วยให้เราสามารถจัดการ Request ก่อนที่มันจะไปถึง API หรือ Page จริง ๆ

Next.js Middleware ทำงานที่ Edge หรือที่เรียกว่า Edge Functions ซึ่งหมายความว่า
✅ ทำงานเร็วมาก เพราะไม่ต้องรอโหลดทั้งเซิร์ฟเวอร์
✅ ใช้งานได้กับทุก Request ที่เข้ามา
✅ ลดภาระของ API Routes และ getServerSideProps

📌 ข้อดีของ Middleware

  • ตรวจสอบสิทธิ์ (Auth) ก่อนเข้าหน้าเว็บ
  • กำหนดเงื่อนไขสำหรับแต่ละ Route
  • Redirect หรือ Rewrite Request ได้
  • บล็อกหรือแก้ไข Header ของ Request


🚀 วิธีใช้ Middleware ใน Next.js

Middleware ใน Next.js จะถูกเก็บไว้ที่ไฟล์ middleware.ts หรือ middleware.js ใน root ของโปรเจกต์

🔹 สร้าง Middleware แรกของคุณ

ไฟล์ middleware.ts

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  console.log('Middleware กำลังทำงาน...')
  return NextResponse.next() // ให้ Request ผ่านไปยังหน้าปลายทาง
}

จากนั้นรันเซิร์ฟเวอร์

npm run dev

ทุกครั้งที่มี Request เข้ามา Middleware จะทำงานก่อนส่งไปที่ Page หรือ API


🔑 ตัวอย่างการใช้งาน Middleware

✨ 1. การ Redirect ผู้ใช้

บางครั้งเราต้องการให้ผู้ใช้ถูก Redirect ไปยังหน้าอื่น โดยอัตโนมัติ

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  const url = req.nextUrl

  if (url.pathname === '/old-page') {
    return NextResponse.redirect(new URL('/new-page', req.url))
  }

  return NextResponse.next()
}

✅ เมื่อผู้ใช้เข้าหน้า /old-page จะถูก Redirect ไปที่ /new-page อัตโนมัติ

🔐 2. ตรวจสอบสิทธิ์ก่อนเข้าหน้าเว็บ (Authentication)

สมมติว่าเรามีหน้า Dashboard ที่ต้องการให้เฉพาะผู้ใช้ที่ล็อกอินเข้าถึงได้

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  const token = req.cookies.get('auth_token')

  if (!token) {
    return NextResponse.redirect(new URL('/login', req.url))
  }

  return NextResponse.next()
}

✅ ถ้าไม่มี Token ผู้ใช้จะถูกส่งไปที่ /login ทันที

🌍 3. เช็คประเทศของผู้ใช้ แล้วเปลี่ยนภาษาอัตโนมัติ

ถ้าต้องการ เปลี่ยนภาษาเว็บตามประเทศของผู้ใช้ เราสามารถใช้ Middleware เช็ค IP แล้ว Redirect ไปยังหน้าที่เหมาะสม

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  const country = req.geo?.country || 'US' // ดึงค่าประเทศจาก IP

  if (country === 'TH') {
    return NextResponse.redirect(new URL('/th', req.url)) // เปลี่ยนไปหน้าเวอร์ชันภาษาไทย
  }

  return NextResponse.next()
}

✅ ถ้าผู้ใช้มาจากไทย จะถูกส่งไปที่ /th อัตโนมัติ

🔄 4. เปลี่ยน Headers ของ Request

บางครั้งเราต้องการ เพิ่ม Headers หรือแก้ไข Headers ก่อนส่งไปยัง API หรือ Page

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  const response = NextResponse.next()
  response.headers.set('X-Custom-Header', 'HelloMiddleware')
  return response
}

✅ เพิ่ม Header X-Custom-Header: HelloMiddleware ในทุก Response

🛠 การกำหนด Middleware ให้ทำงานเฉพาะบางหน้า

บางครั้งเราอาจต้องการให้ Middleware ทำงาน แค่บางหน้า ไม่ใช่ทั้งหมด สามารถใช้ config.matcher ได้

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  return NextResponse.next()
}

// ใช้ Middleware เฉพาะบาง Route
export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*'],
}

✅ Middleware จะทำงานเฉพาะหน้า /dashboard และ /profile เท่านั้น


📌 Middleware กับ API Routes ต่างกันยังไง?

Feature Middleware API Routes
ทำงานเมื่อไหร่? ก่อนส่งไปยัง Page หรือ API เมื่อมีการเรียก API
ทำอะไรได้บ้าง? Redirect, Auth, Modify Request รับ-ส่งข้อมูล API
ทำงานที่ไหน? Edge (เร็วมาก) Server (ปกติ)
ใช้เมื่อไหร่? ตรวจสอบสิทธิ์, Redirect, แก้ไข Headers สร้าง API สำหรับแอป
  • ถ้าต้องการ ดัก Request ก่อนถึงหน้าเว็บ → ใช้ Middleware
  • ถ้าต้องการ สร้าง API Endpoint สำหรับแอป → ใช้ API Routes


🎯 สรุป

Middleware ใน Next.js เป็นเครื่องมือที่ทรงพลังที่ช่วยให้เราสามารถ
✅ Redirect ผู้ใช้ ไปยังหน้าที่เหมาะสม
✅ ตรวจสอบสิทธิ์ ก่อนเข้าถึงข้อมูล
✅ เปลี่ยน Headers ของ Request/Response
✅ ตรวจสอบ IP, Geo Location และเปลี่ยนภาษาเว็บอัตโนมัติ

🔥 ถ้าโปรเจกต์ของคุณต้องการควบคุม Request ก่อนถึงหน้าเว็บ Middleware คือสิ่งที่คุณต้องใช้! 🚀

วันจันทร์ที่ 3 มีนาคม พ.ศ. 2568

การเรียก API ภายใน Next.js อย่างมีประสิทธิภาพ

การเรียก API เป็นเรื่องที่ทุกเว็บแอปต้องทำ ไม่ว่าจะเป็นการดึงข้อมูลจาก Backend, Third-party APIs หรือแม้แต่ API ภายในแอปเอง แต่จะเรียกยังไงให้เร็ว แรง และไม่ทำให้เว็บช้า?

Next.js มีหลายวิธีในการเรียก API ไม่ว่าจะเป็น Server-side fetching, Client-side fetching, Static generation, หรือแม้แต่ ใช้ API Routes ภายในตัวเอง วันนี้เราจะมาเจาะลึกกันว่าควรเลือกใช้วิธีไหนในแต่ละสถานการณ์ เพื่อให้แอปของคุณทำงานเร็วที่สุด 🚀

🔍 วิธีเรียก API ใน Next.js

ใน Next.js เราสามารถเรียก API ได้หลัก ๆ 3 วิธี

  1. Client-side fetching → ใช้ fetch หรือ SWR ใน React Component
  2. Server-side fetching (SSR) → ใช้ getServerSideProps เพื่อโหลดข้อมูลตอนโหลดหน้า
  3. Static generation (SSG) → ใช้ getStaticProps โหลดข้อมูลล่วงหน้า

แต่ละวิธีมีข้อดีข้อเสียต่างกัน เดี๋ยวมาดูรายละเอียดกันเลย!

🎯 1. การเรียก API ฝั่ง Client (Client-side Fetching)

ถ้าข้อมูลที่เราต้องการโหลด ไม่จำเป็นต้องมาเร็วก่อนหน้าแสดงผล เช่น

  •     รายการโพสต์
  •     คอมเมนต์
  •     ข้อมูลที่อัปเดตแบบเรียลไทม์

การใช้ Client-side Fetching จะช่วยให้หน้าเว็บโหลดเร็วขึ้นเพราะมันจะดึงข้อมูลหลังจากโหลดหน้าเสร็จ

🔹 วิธีใช้ fetch กับ useEffect (พื้นฐาน)

import { useEffect, useState } from 'react'

export default function Posts() {
  const [posts, setPosts] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch('/api/posts')
      .then((res) => res.json())
      .then((data) => {
        setPosts(data)
        setLoading(false)
      })
  }, [])

  if (loading) return <p>กำลังโหลดโพสต์...</p>

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

แต่ปัญหาของวิธีนี้คือ ทุกครั้งที่เข้าเพจ มันจะ fetch API ใหม่เสมอ ซึ่งอาจทำให้โหลดข้อมูลซ้ำ ๆ แบบไม่จำเป็น

🔹 วิธีใช้ SWR ให้โหลดเร็วขึ้น

ถ้าอยากให้ ดึงข้อมูลแล้วแคชไว้ ไม่ต้องโหลดใหม่ตลอด SWR เป็นตัวช่วยที่ดี

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then((res) => res.json())

export default function Posts() {
  const { data, error } = useSWR('/api/posts', fetcher)

  if (error) return <p>เกิดข้อผิดพลาด</p>
  if (!data) return <p>กำลังโหลด...</p>

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ SWR ดียังไง?

  •     แคชข้อมูลไว้ ไม่ต้องโหลดใหม่ทุกครั้ง
  •     อัปเดตข้อมูลอัตโนมัติเมื่อมีการเปลี่ยนแปลง
  •     โหลดเร็วขึ้นเพราะดึงจากแคชก่อน แล้วอัปเดตภายหลัง

ถ้าเป็น ข้อมูลที่ต้องอัปเดตบ่อย เช่น Dashboard หรือ Notifications ควรใช้ SWR จะดีที่สุด!

⚡️ 2. การเรียก API ฝั่งเซิร์ฟเวอร์ (SSR)

บางครั้งเราต้องโหลดข้อมูล ก่อนแสดงผลหน้าเว็บ เช่น

  • ข้อมูลผู้ใช้ที่ล็อกอิน
  • สินค้าในตะกร้า
  • รายการสั่งซื้อ

ในกรณีนี้ getServerSideProps เป็นทางเลือกที่ดี เพราะมันจะดึงข้อมูลบนเซิร์ฟเวอร์ก่อนแล้วส่งไปให้หน้าเว็บ

🔹 วิธีใช้ getServerSideProps

export async function getServerSideProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data } }
}

export default function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSR

  • โหลดข้อมูลก่อนแสดงผล → ผู้ใช้เห็นข้อมูลทันที
  • เหมาะกับข้อมูลที่เปลี่ยนแปลงบ่อย เช่น ข้อมูลผู้ใช้
  • รองรับ SEO ดีกว่า Client-side Fetching

❌ ข้อเสีย

  • โหลดช้ากว่าเพราะต้องรอ API ตอบก่อนแสดงผล
  • ถ้า API ช้าจะทำให้หน้าเว็บช้าไปด้วย

ถ้าเป็น API ที่ต้องใช้ข้อมูลสดใหม่ทุกครั้ง เช่น ข้อมูลผู้ใช้ที่ล็อกอินอยู่ getServerSideProps คือทางเลือกที่ดี

🏎 3. โหลด API ล่วงหน้าด้วย Static Generation (SSG)

ถ้าข้อมูลที่เราต้องการ เปลี่ยนแปลงไม่บ่อย เช่น

  • บทความ
  • รายชื่อสินค้า
  • รายการหมวดหมู่

เราสามารถใช้ getStaticProps โหลดข้อมูลตอน Build เวลา Deploy แล้วหน้าเว็บจะโหลดเร็วมาก 🚀

🔹 วิธีใช้ getStaticProps

export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data } }
}

export default function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSG

  • โหลดเร็วมาก เพราะไม่ต้องรอ API ตอนเปิดหน้า
  • เหมาะกับหน้าเว็บที่ข้อมูลเปลี่ยนไม่บ่อย

❌ ข้อเสีย

  • ข้อมูลจะไม่อัปเดตจนกว่าจะ Build ใหม่

ถ้าต้องการให้ SSG รีเฟรชข้อมูลได้เอง สามารถใช้ revalidate เช่น

export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data }, revalidate: 60 } // รีเฟรชทุก 60 วินาที
}

🔥 สรุป: ควรใช้วิธีไหน?

วิธี ใช้เมื่อ ข้อดี ข้อเสีย
Client-side Fetching ข้อมูลเปลี่ยนบ่อย (Dashboard, คอมเมนต์) โหลดเร็ว ไม่ต้องรอ API ไม่ดีต่อ SEO
Server-side Fetching (SSR) ข้อมูลต้องอัปเดตทุกครั้ง เช่น ผู้ใช้ล็อกอิน โหลดก่อนแสดงผล ดีต่อ SEO ช้ากว่า Client-side
Static Generation (SSG) ข้อมูลเปลี่ยนไม่บ่อย เช่น บทความ โหลดเร็วมาก ไม่อัปเดตอัตโนมัติ

เลือกให้เหมาะสมกับโปรเจกต์ของคุณ แล้วเว็บจะทั้งเร็วและมีประสิทธิภาพ! 🚀

วันอาทิตย์ที่ 2 มีนาคม พ.ศ. 2568

การใช้ API Routes เพื่อสร้าง Backend ใน Next.js

ถ้าพูดถึง Next.js หลายคนคงนึกถึง Frontend Framework ที่ช่วยพัฒนาเว็บได้เร็วและแรง แต่รู้หรือเปล่าว่า Next.js ก็มี Backend ในตัว ด้วย?

ใช่แล้ว! Next.js มาพร้อมกับ API Routes ที่ให้เราสร้าง Backend API ได้ง่าย ๆ โดยไม่ต้องใช้ Express, NestJS หรือพวก Backend Framework อื่น ๆ

ในบทความนี้ เราจะมาทำความรู้จัก API Routes ใน Next.js ว่ามันคืออะไร ใช้งานยังไง และมีประโยชน์อะไรบ้าง ถ้าพร้อมแล้วไปลุยกันเลย! 🚀

🤔 API Routes คืออะไร?

API Routes คือฟีเจอร์ของ Next.js ที่ให้เราสร้าง REST API ได้โดยตรงในโปรเจกต์ Next.js เอง โดยไม่ต้องเซ็ตเซิร์ฟเวอร์แยก

📌 ข้อดีของ API Routes

✅ ไม่ต้องใช้ Backend แยก – Next.js จัดการให้
✅ ใช้ JavaScript/TypeScript ล้วน ๆ – ไม่ต้องเรียนรู้ภาษาใหม่
✅ รองรับ Serverless Functions – ทำงานบน Vercel, AWS Lambda, Firebase Functions ได้เลย
✅ ใช้ร่วมกับ Frontend ง่าย – อยู่ในโปรเจกต์เดียวกัน

ถ้าเทียบกับการใช้ Node.js + Express ที่ต้องเซ็ตเซิร์ฟเวอร์เอง API Routes ของ Next.js จะง่ายกว่าเยอะ!

🛠 สร้าง API Routes แรกของคุณ

ใน Next.js ไฟล์ API Routes จะอยู่ใน /pages/api/ เช่น

📂 โครงสร้างโฟลเดอร์

my-next-app/
 ├── pages/
 │   ├── index.js
 │   ├── about.js
 │   ├── api/       <-- โฟลเดอร์ API
 │   │   ├── hello.js   <-- ไฟล์ API Route
 │   │   ├── users.js
 │   │   ├── posts.js

ลองสร้างไฟล์ /pages/api/hello.js แล้วใส่โค้ดนี้ลงไป

export default function handler(req, res) {
  res.status(200).json({ message: 'สวัสดีจาก API Routes!' })
}

✨ ลองรันเซิร์ฟเวอร์

npm run dev
# หรือ
yarn dev

แล้วเข้า http://localhost:3000/api/hello จะได้ JSON แบบนี้

{
  "message": "สวัสดีจาก API Routes!"
}

ง่ายมากใช่ไหม? ไม่ต้องติดตั้ง Express หรือเซ็ต Server อะไรให้ยุ่งยากเลย!

🚀 การใช้ HTTP Methods (GET, POST, PUT, DELETE)

API Routes รองรับทุก HTTP Method เช่น GET, POST, PUT, DELETE โดยเช็คจาก req.method

✨ ตัวอย่าง API รองรับหลาย Method

ไฟล์ /pages/api/users.js

export default function handler(req, res) {
  if (req.method === 'GET') {
    res.status(200).json({ users: ['Alice', 'Bob', 'Charlie'] })
  } else if (req.method === 'POST') {
    res.status(201).json({ message: 'สร้างผู้ใช้ใหม่เรียบร้อย!' })
  } else {
    res.status(405).json({ error: 'Method ไม่รองรับ' })
  }
}

🔹 GET → ดึงข้อมูลผู้ใช้
🔹 POST → สร้างผู้ใช้ใหม่
🔹 อื่น ๆ → ส่ง 405 Method Not Allowed

ลองยิง API ดู! 🚀

curl -X GET http://localhost:3000/api/users
curl -X POST http://localhost:3000/api/users


🔄 อ่านค่า Query Parameters

ถ้าต้องการดึงค่าจาก Query String (เช่น /api/user?id=123) เราสามารถใช้ req.query ได้เลย

ไฟล์ /pages/api/user.js

export default function handler(req, res) {
  const { id } = req.query

  if (!id) {
    return res.status(400).json({ error: 'กรุณาระบุ id' })
  }

  res.status(200).json({ user: { id, name: 'John Doe' } })
}

✨ ทดสอบ API

curl http://localhost:3000/api/user?id=456

📌 output

{
  "user": { "id": "456", "name": "John Doe" }
}


📬 รับข้อมูลจาก Body (POST Method)

ถ้าต้องการรับข้อมูลจาก Body ของ Request เช่นเวลาส่งฟอร์มหรือ JSON Data เราสามารถใช้ req.body ได้เลย

ไฟล์ /pages/api/login.js

export default function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method ไม่รองรับ' })
  }

  const { username, password } = req.body

  if (username === 'admin' && password === '1234') {
    res.status(200).json({ message: 'เข้าสู่ระบบสำเร็จ!' })
  } else {
    res.status(401).json({ error: 'ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง' })
  }
}

✨ ทดสอบ API

curl -X POST http://localhost:3000/api/login -H "Content-Type: application/json" -d '{"username": "admin", "password": "1234"}'

📌 output

{
  "message": "เข้าสู่ระบบสำเร็จ!"
}

🔒 ใช้ Middleware กับ API Routes

ถ้าต้องการตรวจสอบ JWT Token หรือทำ Authentication ก่อนเข้าถึง API สามารถใช้ Middleware ได้ง่าย ๆ

ไฟล์ /pages/api/secure.js

export default function handler(req, res) {
  const { authorization } = req.headers

  if (!authorization || authorization !== 'Bearer mysecrettoken') {
    return res.status(403).json({ error: 'ไม่ได้รับอนุญาต' })
  }

  res.status(200).json({ message: 'เข้าถึงข้อมูลสำเร็จ!' })
}

✨ ทดสอบ API (ล้มเหลว)

curl http://localhost:3000/api/secure

📌 output

{
  "error": "ไม่ได้รับอนุญาต"
}

✨ ทดสอบ API (สำเร็จ)

curl -H "Authorization: Bearer mysecrettoken" http://localhost:3000/api/secure

📌 output

{
  "message": "เข้าถึงข้อมูลสำเร็จ!"
}

🎯 สรุป

API Routes เป็นฟีเจอร์ที่ช่วยให้เราสร้าง Backend API ใน Next.js ได้ง่าย ๆ โดยไม่ต้องติดตั้งเซิร์ฟเวอร์แยก เหมาะกับการทำงานแบบ Fullstack ที่ต้องการพัฒนา Frontend และ Backend ไปพร้อมกัน

📌 จุดเด่นของ API Routes

✅ ใช้งานง่าย – ไม่ต้องเซ็ตเซิร์ฟเวอร์เอง
✅ รองรับ HTTP Methods (GET, POST, PUT, DELETE)
✅ ใช้ Query Parameters และ Request Body ได้
✅ รองรับ Middleware เช่น Authentication

ถ้าคุณใช้ Next.js อยู่แล้ว ลองใช้ API Routes ดู แล้วจะรู้ว่ามัน โคตรสะดวก! 🚀

วันเสาร์ที่ 1 มีนาคม พ.ศ. 2568

การใช้ SWR ใน Next.js เพื่อดึงข้อมูลแบบ Client-side

ในโลกของการพัฒนาเว็บแอปพลิเคชัน ฝั่ง Frontend ต้องมีวิธีดึงข้อมูลจาก API อย่างมีประสิทธิภาพ ซึ่งใน Next.js มีหลายแนวทางให้เลือกใช้ เช่น getServerSideProps (SSR), getStaticProps (SSG), หรือ Client-side Fetching ซึ่งแต่ละวิธีก็มีข้อดีข้อเสียต่างกันไป

ถ้าพูดถึงการดึงข้อมูลแบบ Client-side แล้ว SWR เป็นตัวเลือกที่หลายคนชอบ เพราะมันช่วยให้การ fetch ข้อมูลลื่นไหล อัปเดตอัตโนมัติ และยังจัดการแคชได้อย่างฉลาด วันนี้เราจะมาทำความรู้จัก SWR และดูวิธีใช้งานใน Next.js กันแบบเข้าใจง่าย ๆ

🔍 SWR คืออะไร?

SWR ย่อมาจาก Stale-While-Revalidate เป็นแนวคิดที่ช่วยให้การดึงข้อมูลเร็วและสดใหม่ตลอดเวลา โดยที่ไม่ต้องให้ผู้ใช้รอนานเกินไป โดยถูกพัฒนาโดยทีมเดียวกับ Next.js (Vercel) ทำให้มันเหมาะกับการใช้ในโปรเจ็กต์ที่พัฒนาโดย Next.js มาก

หลักการของ SWR คือ

  • คืนค่าข้อมูลเก่าจากแคชก่อน เพื่อให้ผู้ใช้เห็นข้อมูลเร็วที่สุด
  • ดึงข้อมูลใหม่จาก API อยู่เบื้องหลัง
  • อัปเดตข้อมูลใหม่ ใน UI อัตโนมัติ

ฟังดูดีใช่ไหม? เพราะมันช่วยให้การโหลดข้อมูลไม่กระตุก และมีประสบการณ์ใช้งานที่ดีขึ้น

🚀 ติดตั้ง SWR

ก่อนอื่น ถ้ายังไม่ได้ติดตั้ง SWR สามารถติดตั้งได้ง่าย ๆ ด้วยคำสั่งนี้

npm install swr
# หรือถ้าใช้ yarn
yarn add swr

เสร็จแล้วก็พร้อมลุย! 🎉

🛠 วิธีใช้ SWR เบื้องต้น

SWR ใช้งานง่ายมาก ๆ เพียงแค่ import และใช้ useSWR ใน React Component

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then(res => res.json())

export default function Profile() {
  const { data, error } = useSWR('/api/user', fetcher)

  if (error) return <div>โหลดข้อมูลไม่สำเร็จ 😢</div>
  if (!data) return <div>กำลังโหลดข้อมูล... ⏳</div>

  return (
    <div>
      <h1>สวัสดี, {data.name}!</h1>
      <p>อีเมล: {data.email}</p>
    </div>
  )
}

อธิบายโค้ด

  • เราใช้ useSWR เพื่อดึงข้อมูลจาก /api/user
  • fetcher คือฟังก์ชันที่ใช้ดึงข้อมูลจาก API
  • ถ้ามี error จะแสดงข้อความผิดพลาด
  • ถ้าข้อมูลยังมาไม่ถึง จะแสดงข้อความ กำลังโหลด...
  • ถ้าทุกอย่างเรียบร้อยแล้ว ก็โชว์ข้อมูลที่ดึงมาได้

ข้อดีของวิธีนี้คือ ไม่ต้องใช้ useEffect หรือจัดการ state เองเลย เพราะ SWR จัดการให้หมด!

⚡️ ทำไม SWR ถึงดีกว่า useEffect + fetch?

บางคนอาจสงสัยว่า "แล้วทำไมไม่ใช้ useEffect กับ fetch ตรง ๆ ล่ะ?" คำตอบคือ SWR ดีกว่าเพราะ

✅ จัดการแคชให้อัตโนมัติ – ไม่ต้องโหลดข้อมูลซ้ำถ้ายังอยู่ในแคช
✅ อัปเดตข้อมูลเมื่อมีการเปลี่ยนแปลง – ไม่ต้อง reload หน้าเอง
✅ รองรับการ Revalidate อัตโนมัติ – ดึงข้อมูลใหม่เมื่อลูกค้ากลับมาที่หน้าเว็บ
✅ รองรับการดึงข้อมูลแบบ on-focus & re-fetch on reconnect – ไม่ต้องกดรีเฟรชเอง

ถ้าใช้ useEffect และ fetch เราต้องเขียนโค้ดจัดการแคชเอง ซึ่งยุ่งยากและซับซ้อนกว่า

🔄 ตัวอย่างการใช้ Mutate และ Revalidate

ถ้าต้องการให้ข้อมูลอัปเดตทันทีโดยไม่ต้องรอ SWR รีเฟรชเอง สามารถใช้ mutate ได้

import useSWR, { mutate } from 'swr'

const fetcher = (url) => fetch(url).then(res => res.json())

export default function Dashboard() {
  const { data } = useSWR('/api/stats', fetcher)

  return (
    <div>
      <h1>ยอดผู้ใช้งาน: {data ? data.users : 'กำลังโหลด...'}</h1>
      <button onClick={() => mutate('/api/stats')}>โหลดข้อมูลใหม่</button>
    </div>
  )
}

เมื่อกดปุ่ม โหลดข้อมูลใหม่ ระบบจะดึงข้อมูลใหม่จาก API ทันที

🔐 ใช้ SWR กับ Authentication

SWR เหมาะกับระบบที่ต้องใช้ Token Authentication เช่น JWT หรือ OAuth เพราะสามารถส่ง Header ไปกับทุก Request ได้ง่าย ๆ

import useSWR from 'swr'

const fetcher = (url) =>
  fetch(url, {
    headers: {
      Authorization: `Bearer ${localStorage.getItem('token')}`,
    },
  }).then((res) => res.json())

export default function UserProfile() {
  const { data, error } = useSWR('/api/profile', fetcher)

  if (error) return <div>โหลดข้อมูลไม่สำเร็จ</div>
  if (!data) return <div>กำลังโหลด...</div>

  return <h1>ชื่อผู้ใช้: {data.username}</h1>
}


🔥 การใช้งาน SWR กับ GraphQL

ถ้าใช้ GraphQL เราก็สามารถใช้ SWR ได้ โดยเปลี่ยนจาก fetch เป็นการส่ง Query ไปยัง API

const fetcher = (query) =>
  fetch('/graphql', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query }),
  }).then((res) => res.json())

const GET_USER = `
  {
    user {
      name
      email
    }
  }
`

export default function UserProfile() {
  const { data, error } = useSWR(GET_USER, fetcher)

  if (error) return <div>โหลดข้อมูลไม่สำเร็จ</div>
  if (!data) return <div>กำลังโหลด...</div>

  return <h1>ชื่อ: {data.user.name}</h1>
}

📌 สรุป

SWR เป็นเครื่องมือที่ช่วยให้การดึงข้อมูลแบบ Client-side ง่ายขึ้น โดยที่ไม่ต้องจัดการแคชเอง รองรับการอัปเดตข้อมูลอัตโนมัติ และมีประสิทธิภาพสูงกว่าการใช้ useEffect + fetch แบบเดิม ๆ
✅ เหมาะกับ

  • ดึงข้อมูลที่เปลี่ยนแปลงบ่อย เช่น ยอดไลก์, คอมเมนต์, จำนวนผู้ใช้
  • แสดงข้อมูลให้ผู้ใช้เร็วที่สุด โดยใช้แคช
  • อัปเดตข้อมูลอัตโนมัติ โดยไม่ต้องรีเฟรชหน้า

ถ้าคุณใช้ Next.js อยู่แล้ว ลองเอา SWR ไปใช้ดู รับรองว่าชีวิตง่ายขึ้นแน่นอน! 🚀

การใช้ Image Optimization ใน Next.js: โหลดไว SEO ดี ประหยัดแบนด์วิธ!

เคยเจอปัญหาเว็บโหลดช้าเพราะรูปภาพขนาดใหญ่หรือเปล่า? 📷 ถ้าใช่ Next.js มีฟีเจอร์ Image Optimization ที่ช่วยให้รูปภาพโหลดเร็วขึ้น อัตโนมัติ ไม...