แสดงบทความที่มีป้ายกำกับ User Experience แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ User Experience แสดงบทความทั้งหมด

วันพฤหัสบดีที่ 3 เมษายน พ.ศ. 2568

การใช้ Toast Notifications ใน Next.js: แจ้งเตือนแบบโปร ไม่ต้องรีโหลดหน้า

เคยเจอปัญหานี้ไหม? กดปุ่มแล้วไม่รู้ว่าระบบทำงานหรือยัง ส่งฟอร์มแล้วไม่แน่ใจว่าผ่านหรือไม่ หรืออยากให้เว็บมีแจ้งเตือนที่ดูดีแต่ไม่อยากเขียนเองให้ยุ่งยาก

วันนี้เราจะมาเรียนรู้วิธีใช้ Toast Notifications ใน Next.js แบบง่ายๆ โดยใช้ react-hot-toast ไลบรารีสุดเทพที่ช่วยให้แจ้งเตือนแบบลื่นไหล ดูดี และใช้งานง่าย

🔥 ทำไมต้องใช้ Toast Notifications?

Toast Notifications คือ ข้อความแจ้งเตือนแบบชั่วคราว ที่แสดงขึ้นมาในเว็บเมื่อมีเหตุการณ์บางอย่างเกิดขึ้น เช่น:

✅ แจ้งเตือนเมื่อทำรายการสำเร็จ ✅
✅ แจ้งเตือนข้อผิดพลาด (เช่น ฟอร์มไม่ถูกต้อง) ❌
✅ แจ้งเตือนระหว่างโหลดข้อมูล ⏳

Toast ดีๆ ควรเป็น Non-intrusive (ไม่รบกวน) และ Auto-dismiss (หายไปเอง) เพื่อไม่ให้ผู้ใช้รำคาญ

🚀 ติดตั้ง react-hot-toast ใน Next.js

เราจะใช้ react-hot-toast เพราะมันใช้ง่ายและทำงานได้ดีกับ Next.js

ติดตั้งแพ็กเกจ

npm install react-hot-toast

หรือถ้าใช้ Yarn

yarn add react-hot-toast


🎨 ตั้งค่า ToastProvider

ToastProvider เป็นคอมโพเนนต์ที่ช่วยให้เราสามารถใช้ toast ได้ทั่วแอป ต้องเพิ่มใน _app.js

แก้ไข pages/_app.js

import { Toaster } from 'react-hot-toast';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Toaster position="top-right" reverseOrder={false} />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

🔹 position="top-right" – ให้ toast แสดงที่มุมขวาบน
🔹 reverseOrder={false} – ให้ข้อความใหม่ขึ้นด้านล่าง


🎯 ใช้งาน toast แจ้งเตือน

react-hot-toast ใช้งานง่ายมาก มีฟังก์ชันหลักๆ เช่น

  • toast.success("ข้อความ") ✅ แจ้งเตือนสำเร็จ
  • toast.error("ข้อความ") ❌ แจ้งเตือนข้อผิดพลาด
  • toast.loading("กำลังโหลด...") ⏳ แจ้งเตือนระหว่างโหลด
  • toast.dismiss() 🚫 ลบ toast ที่กำลังแสดง


💡 ตัวอย่างการใช้งาน toast ในปุ่ม

สร้างไฟล์ pages/index.js และเพิ่มปุ่มที่กดแล้วแจ้งเตือน

import toast from 'react-hot-toast';

export default function Home() {
  const notifySuccess = () => toast.success('บันทึกข้อมูลสำเร็จ! 🎉');
  const notifyError = () => toast.error('เกิดข้อผิดพลาด ❌');
  const notifyLoading = () => {
    const toastId = toast.loading('กำลังโหลดข้อมูล...');
    setTimeout(() => toast.success('โหลดสำเร็จ ✅', { id: toastId }), 2000);
  };

  return (
    <div className="p-10">
      <h1 className="text-2xl font-bold mb-4">🔔 ทดลองใช้ Toast Notifications</h1>
      <button onClick={notifySuccess} className="bg-green-500 text-white px-4 py-2 mr-2 rounded">✅ แจ้งเตือนสำเร็จ</button>
      <button onClick={notifyError} className="bg-red-500 text-white px-4 py-2 mr-2 rounded">❌ แจ้งเตือนข้อผิดพลาด</button>
      <button onClick={notifyLoading} className="bg-blue-500 text-white px-4 py-2 rounded">⏳ แจ้งเตือนระหว่างโหลด</button>
    </div>
  );
}

🔍 อธิบายโค้ด:

  • toast.success() ใช้แจ้งเตือนเมื่อทำรายการสำเร็จ
  • toast.error() ใช้แจ้งเตือนเมื่อเกิดข้อผิดพลาด
  • toast.loading() ใช้แจ้งเตือนว่ากำลังโหลดข้อมูล และอัปเดตเป็น toast.success() หลังจากโหลดเสร็จ


🎨 ปรับแต่งสไตล์ Toast

เราสามารถ กำหนดสไตล์ ของ toast ได้ เช่น เปลี่ยนสีพื้นหลัง เปลี่ยนไอคอน หรือกำหนดเวลาหายไปเอง

1️⃣ กำหนดเวลาให้ toast หายไปอัตโนมัติ

toast.success('บันทึกเรียบร้อย!', {
  duration: 5000, // แสดงผล 5 วินาที
});

2️⃣ เปลี่ยนสีและไอคอน

toast('🛑 คำเตือน: โปรดตรวจสอบข้อมูล', {
  style: {
    border: '1px solid red',
    padding: '16px',
    color: 'red',
  },
});

3️⃣ กำหนด animation

toast.success('ทำสำเร็จ!', {
  style: { animation: 'bounce 1s ease-in-out' },
});


🔄 ใช้ Toast กับ API Requests

ลองใช้ toast กับ API จริงๆ เช่น fetch()

const fetchData = async () => {
  const toastId = toast.loading('กำลังโหลดข้อมูล...');

  try {
    const response = await fetch('/api/data');
    const result = await response.json();

    toast.success('โหลดข้อมูลสำเร็จ!', { id: toastId });
  } catch (error) {
    toast.error('โหลดข้อมูลล้มเหลว', { id: toastId });
  }
};

🔍 อธิบาย:

  • toast.loading() แจ้งเตือนว่ากำลังโหลด
  • ถ้าโหลดสำเร็จ → toast.success()
  • ถ้าเกิดข้อผิดพลาด → toast.error()


📌 ใช้ Toast กับฟอร์ม

ในฟอร์มเราสามารถใช้ toast แจ้งเตือนว่า กรอกข้อมูลถูกต้องหรือไม่

const handleSubmit = (e) => {
  e.preventDefault();
 
  if (!email) {
    toast.error('กรุณากรอกอีเมล!');
    return;
  }

  toast.success('ส่งข้อมูลสำเร็จ!');
};

🏆 สรุป

✅ react-hot-toast ใช้งานง่ายมาก
✅ ใช้กับ API Requests, ฟอร์ม และปุ่มต่างๆ ได้
✅ ปรับแต่งสไตล์และอนิเมชันได้
✅ ไม่ต้องรีโหลดหน้า ก็แจ้งเตือนได้แบบสวยๆ

พร้อมใช้ Toast แจ้งเตือนให้เว็บของคุณดูโปรขึ้นหรือยัง? 🚀

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

วิธีใช้ Magic Link Authentication ใน Next.js แบบเข้าใจง่าย

ถ้าเบื่อรหัสผ่าน มาลอง Magic Link กันเถอะ!

Magic Link Authentication เป็นวิธีล็อกอินที่ไม่ต้องใช้รหัสผ่าน ผู้ใช้แค่ใส่อีเมล แล้วระบบจะส่งลิงก์ให้คลิกเพื่อเข้าสู่ระบบ ง่าย สะดวก และปลอดภัยกว่าการจำรหัสผ่านเยอะ

ในบทความนี้ เราจะมาดูกันว่า Next.js ใช้ Magic Link ได้ยังไง โดยใช้ NextAuth.js (ตัวช่วยจัดการการยืนยันตัวตนใน Next.js) พร้อมกับ Resend (บริการส่งอีเมลที่ใช้ง่ายและเร็ว)

🎩 ทำไมต้อง Magic Link?

✅ ไม่ต้องจำรหัสผ่าน

  • ชีวิตเรามีรหัสผ่านเยอะเกินไปแล้ว! Magic Link ตัดปัญหานี้ออกไป

✅ ปลอดภัยกว่ารหัสผ่านปกติ

  •     ไม่มีรหัสผ่านให้แฮก (เพราะไม่มีเลย 🤣)
  •     ใช้ one-time link (ลิงก์ใช้ได้ครั้งเดียว) ลดความเสี่ยง

✅ UX ดีขึ้น

  •     ล็อกอินง่าย ไม่ต้องพิมพ์อะไรเยอะ
  •     ลดปัญหา "ลืมรหัสผ่าน"


สรุป: Magic Link = ง่าย + ปลอดภัย + ดีต่อผู้ใช้


🚀 มาเริ่มกันเลย!

1️⃣ สร้างโปรเจ็กต์ Next.js

ถ้ายังไม่มีโปรเจ็กต์ Next.js ให้สร้างใหม่ก่อน

npx create-next-app@latest magic-link-demo
cd magic-link-demo
npm install

2️⃣ ติดตั้ง NextAuth.js และ Resend

npm install next-auth resend

3️⃣ ตั้งค่า NextAuth.js

สร้างไฟล์ pages/api/auth/[...nextauth].js

import NextAuth from "next-auth";
import EmailProvider from "next-auth/providers/email";
import { Resend } from "resend";

const resend = new Resend(process.env.RESEND_API_KEY);

export default NextAuth({
  providers: [
    EmailProvider({
      async sendVerificationRequest({ identifier: email, url }) {
        await resend.emails.send({
          from: "no-reply@yourdomain.com",
          to: email,
          subject: "Magic Link Login",
          html: `<p>Click <a href="${url}">here</a> to log in.</p>`,
        });
      },
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
});

🔹 อธิบายโค้ด:

  •     ใช้ EmailProvider จาก NextAuth.js
  •     เมื่อผู้ใช้ใส่อีเมล ระบบจะส่ง Magic Link ไปที่อีเมลนั้น
  •     ใช้ Resend เป็นตัวช่วยส่งอีเมล
  •     ลิงก์ที่ส่งไปเป็นแบบ one-time link


🎨 สร้างหน้า Login

สร้างไฟล์ pages/login.js

import { signIn } from "next-auth/react";

export default function Login() {
  const handleLogin = async (e) => {
    e.preventDefault();
    const email = e.target.email.value;
    await signIn("email", { email });
  };

  return (
    <div>
      <h1>Magic Link Login</h1>
      <form onSubmit={handleLogin}>
        <input type="email" name="email" placeholder="Enter your email" required />
        <button type="submit">Send Magic Link</button>
      </form>
    </div>
  );
}

🔹 อธิบายโค้ด:

  •     มีฟอร์มให้ผู้ใช้กรอกอีเมล
  •     กดปุ่มแล้วระบบจะเรียก signIn("email", { email }) เพื่อขอ Magic Link
  •     NextAuth.js จะจัดการส่งอีเมลให้เอง


🎯 ทดสอบใช้งาน

  1.     รันเซิร์ฟเวอร์ npm run dev
  2.     เข้าไปที่ /login
  3.     ใส่อีเมล แล้วกดส่ง
  4.     เปิดอีเมล กดลิงก์ แล้วเข้าสู่ระบบ! 🎉



🔥 เพิ่มเติม: ตั้งค่า ENV

สร้างไฟล์ .env.local

NEXTAUTH_SECRET=your-secret-key
RESEND_API_KEY=your-resend-api-key
NEXTAUTH_URL=http://localhost:3000


❓ คำถามที่พบบ่อย

1️⃣ ถ้าไม่มีอีเมล จะล็อกอินยังไง?

Magic Link ต้องใช้อีเมลเท่านั้น ถ้าผู้ใช้ไม่มีอีเมล อาจต้องใช้ OAuth (เช่น Google, Facebook)

2️⃣ Magic Link ปลอดภัยจริงไหม?

ค่อนข้างปลอดภัย แต่ควร:

  •     ใช้ one-time link
  •     ลิงก์ควรหมดอายุเร็ว (เช่น 10 นาที)
  •     ใช้ HTTPS เสมอ

3️⃣ ถ้าอีเมลไปไม่ถึงทำไง?

  •     เช็กโฟลเดอร์ Spam
  •     ใช้อีเมลจากผู้ให้บริการที่น่าเชื่อถือ
  •     ลองเปลี่ยนไปใช้ SMTP แทน Resend


🎉 สรุป

  •     Magic Link คือการล็อกอินแบบไม่ใช้รหัสผ่าน
  •     NextAuth.js + Resend ช่วยให้ใช้งาน Magic Link ได้ง่าย
  •     UX ดีขึ้น ปลอดภัยขึ้น และลดปัญหาลืมรหัสผ่าน

ลองทำกันดู แล้วจะติดใจ! 😉

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

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