วันศุกร์ที่ 28 กุมภาพันธ์ พ.ศ. 2568

การใช้ useEffect และ useState สำหรับ Client-side Rendering (CSR)

ถ้าคุณเป็นสาย React น่าจะคุ้นเคยกับการใช้ useState และ useEffect กันอยู่แล้ว แต่เคยสงสัยไหมว่า เวลาเราทำ Client-side Rendering (CSR) ควรใช้สองตัวนี้ยังไงให้ถูกต้อง?

ในบทความนี้ เราจะมาดูวิธีใช้ useState และ useEffect ในการจัดการข้อมูลแบบ CSR (Client-side Rendering) พร้อมตัวอย่างโค้ดจริง และข้อควรระวังที่ต้องระวัง ถ้าพร้อมแล้ว ไปดูกันเลย! 🚀

🎯 Client-side Rendering (CSR) คืออะไร?

ก่อนจะไปดู useState และ useEffect มาทำความเข้าใจ CSR (Client-side Rendering) กันก่อน

📌 CSR คือการเรนเดอร์หน้าเว็บบนฝั่งไคลเอนต์ (Client-side) โดยใช้ JavaScript ซึ่งหมายความว่า ทุกอย่างถูกโหลดผ่านเบราว์เซอร์ แทนที่จะให้เซิร์ฟเวอร์ส่งหน้า HTML มาให้แบบสมบูรณ์

🔍 ลักษณะของ CSR:

  • เมื่อเข้าเว็บครั้งแรก เบราว์เซอร์จะโหลดไฟล์ HTML + JavaScript
  • JavaScript จะรันบนฝั่งไคลเอนต์ เพื่อสร้าง UI และดึงข้อมูลจาก API
  • เหมาะกับแอปที่ต้องการ อินเตอร์แอคทีฟสูง เช่น Dashboard หรือ Web App
  • แต่ SEO อาจไม่ดี เพราะหน้าเว็บไม่มีข้อมูล HTML ให้บอทอ่าน (ต้องใช้ Next.js + SSR/SSG แก้ปัญหา)


🛠 การใช้ useState และ useEffect สำหรับ CSR

📌 useState คืออะไร?

useState เป็น React Hook ที่ใช้จัดการ state (ข้อมูลที่เปลี่ยนแปลงได้) ในคอมโพเนนต์ ฟังก์ชันนี้ช่วยให้เราสร้างตัวแปร state และอัปเดตค่าได้ง่าย ๆ

📌 useEffect คืออะไร?

useEffect เป็น React Hook ที่ใช้จัดการ side effects เช่น

  • เรียก API
  • เปลี่ยนชื่อเอกสาร (document.title)
  • ตั้งค่า setTimeout หรือ setInterval


🏗 ตัวอย่างการใช้ useState และ useEffect ใน CSR

มาดูกันว่า เราสามารถใช้ useState และ useEffect ใน CSR ได้ยังไง โดยสมมติว่าเราต้องการ ดึงข้อมูลผู้ใช้จาก API และแสดงผลในเว็บ

1. โหลดข้อมูลจาก API ด้วย useEffect

import React, { useState, useEffect } from 'react';

const UsersList = () => {
  const [users, setUsers] = useState([]); // ใช้ useState เก็บข้อมูลผู้ใช้
  const [loading, setLoading] = useState(true); // ใช้ state เช็กว่ากำลังโหลดข้อมูลอยู่ไหม

  useEffect(() => {
    // ดึงข้อมูลจาก API เมื่อคอมโพเนนต์โหลดครั้งแรก
    fetch('https://jsonplaceholder.typicode.com/users')
      .then((response) => response.json())
      .then((data) => {
        setUsers(data); // อัปเดต state
        setLoading(false); // ปิดสถานะ loading
      });
  }, []); // ใส่ [] หมายความว่าจะรันแค่ครั้งเดียวตอนโหลดหน้า

  return (
    <div>
      <h1>รายชื่อผู้ใช้</h1>
      {loading ? <p>กำลังโหลดข้อมูล...</p> : null}
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

export default UsersList;

🔍 อธิบายโค้ด

  • ใช้ useState([]) เพื่อเก็บข้อมูลผู้ใช้
  • ใช้ useEffect เพื่อเรียก API ตอนคอมโพเนนต์โหลดครั้งแรก
  • ใช้ setUsers(data) เพื่ออัปเดตข้อมูล
  • ใช้ setLoading(false) เพื่อปิดสถานะโหลด


2. ใช้ useEffect จัดการ Event Listener

สมมติว่าเราต้องการให้หน้าเว็บ เช็กขนาดหน้าจอ (window size) และอัปเดตทุกครั้งที่เปลี่ยนขนาด

import React, { useState, useEffect } from 'react';

const WindowSize = () => {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);

    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize); // ลบ Event Listener ตอนคอมโพเนนต์ unmount
    };
  }, []);

  return (
    <div>
      <h1>ขนาดหน้าจอ: {width}px</h1>
    </div>
  );
};

export default WindowSize;

🔍 อธิบายโค้ด

  • ใช้ useState เพื่อเก็บค่าความกว้างของหน้าจอ
  • ใช้ useEffect เพิ่ม event listener resize ตอนโหลด
  • ใช้ return () => {} เพื่อลบ event listener ตอนคอมโพเนนต์ถูกถอดออก


🔥 ข้อควรระวังในการใช้ useEffect และ useState

⚠️ 1. อย่าดึง API ใน useEffect แบบไม่มี Dependency Array

ถ้าคุณลืมใส่ [] มันจะรันซ้ำ ทุกครั้งที่คอมโพเนนต์ re-render ทำให้ API ถูกเรียกหลายรอบเกินไป

❌ โค้ดผิด:

useEffect(() => {
  fetchData(); // จะเรียก API ทุกครั้งที่ state เปลี่ยน
});

✅ โค้ดที่ถูกต้อง:

useEffect(() => {
  fetchData(); // เรียก API แค่ครั้งเดียว
}, []);

⚠️ 2. อย่าอัปเดต state ใน useEffect โดยไม่มีเงื่อนไข

ถ้าเราอัปเดต state โดยไม่มีเงื่อนไข มันจะทำให้เกิด Infinite Loop ได้

❌ โค้ดผิด:

useEffect(() => {
  setCount(count + 1); // ทำให้เกิดลูป เพราะการอัปเดต state ทำให้ useEffect รันใหม่
}, [count]);

✅ โค้ดที่ถูกต้อง:

useEffect(() => {
  if (count < 10) setCount(count + 1);
}, [count]); // ตรวจสอบก่อนอัปเดต state


📌 สรุป

  • useState ใช้เก็บข้อมูลที่เปลี่ยนแปลงได้ในคอมโพเนนต์
  • useEffect ใช้ดึงข้อมูลจาก API, จัดการ Event Listener, และทำงานที่ต้องเกิดหลังจาก render
  • CSR เหมาะกับเว็บที่ต้องการโต้ตอบเยอะ แต่ไม่เหมาะกับ SEO
  • ควรระวังการใช้ useEffect ไม่ให้เกิด Infinite Loop หรือ API ถูกเรียกซ้ำ

ถ้าคุณเข้าใจการใช้ useState และ useEffect แล้ว คุณสามารถพัฒนาเว็บแบบ CSR ได้อย่างมีประสิทธิภาพ 🚀

วันพฤหัสบดีที่ 27 กุมภาพันธ์ พ.ศ. 2568

การใช้ getInitialProps และเมื่อไหร่ควรใช้

ถ้าคุณเคยใช้ Next.js มาสักพัก น่าจะเคยได้ยินเกี่ยวกับ getInitialProps ซึ่งเป็นฟังก์ชันที่ใช้ดึงข้อมูลมาแสดงบนหน้าเว็บได้ทั้ง ฝั่งเซิร์ฟเวอร์ (Server-side) และ ฝั่งไคลเอนต์ (Client-side) แต่เดี๋ยวก่อน! ทำไมมันถึงดูเหมือน SSR และ CSR รวมกันล่ะ?

วันนี้เราจะมาเจาะลึกว่า getInitialProps ทำงานยังไง ควรใช้เมื่อไหร่ และ Next.js เวอร์ชันใหม่ยังควรใช้มันอยู่มั้ย? ถ้าพร้อมแล้ว ไปดูกันเลย! 🚀

📌 getInitialProps คืออะไร?

getInitialProps เป็นฟังก์ชันพิเศษของ Next.js ที่ใช้ดึงข้อมูลให้กับ Page Component โดยสามารถทำงานได้ทั้งฝั่ง เซิร์ฟเวอร์ และ ไคลเอนต์ ขึ้นอยู่กับว่าเพจนั้นโหลดมาแบบไหน

  • รันบนเซิร์ฟเวอร์ ถ้าผู้ใช้เข้าหน้าเว็บโดยตรง (getInitialProps ทำงานเหมือน SSR)
  • รันบนไคลเอนต์ ถ้าผู้ใช้ไปยังหน้านั้นผ่านการ Client-side Navigation (เช่น กดลิงก์ไปที่หน้าใหม่โดยไม่โหลดเว็บใหม่)

🔍 ข้อดีของ getInitialProps

  • ใช้ดึงข้อมูลได้ทั้งจากเซิร์ฟเวอร์และไคลเอนต์
  • ใช้กับ Custom App (_app.js) ได้
  • เหมาะสำหรับแอปที่ต้องการโหลดข้อมูลแบบ Hybrid (SSR + CSR)

❌ ข้อเสียของ getInitialProps

  • ทำให้ Automatic Static Optimization ใช้ไม่ได้ เพราะ Next.js มองว่ามันเป็น Dynamic Page
  • ช้ากว่า getStaticProps เพราะต้องรันโค้ดทุกครั้งที่โหลดหน้า
  • Next.js ไม่แนะนำให้ใช้ในเวอร์ชันใหม่ เนื่องจาก SSR และ SSG มีฟังก์ชันที่แยกกันชัดเจนกว่า


📌 วิธีใช้ getInitialProps

ลองมาดูตัวอย่างการใช้งานกัน สมมติว่าเราต้องการดึงข้อมูลจาก API และแสดงผลในหน้าเว็บ

import React from 'react';

const Blog = ({ posts }) => {
  return (
    <div>
      <h1>บล็อก (getInitialProps)</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
};

Blog.getInitialProps = async () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await res.json();

  return { posts };
};

export default Blog;

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

  • เราสร้างคอมโพเนนต์ Blog และรับ posts เป็น props
  • ใช้ Blog.getInitialProps เพื่อดึงข้อมูลจาก API
  • ถ้าผู้ใช้โหลดหน้า /blog ตรง ๆ → getInitialProps จะรันบนเซิร์ฟเวอร์
  • ถ้าผู้ใช้กดลิงก์มาจากหน้าอื่น → getInitialProps จะรันบนไคลเอนต์


📌 getInitialProps ใช้กับ _app.js ได้!

หนึ่งในข้อดีของ getInitialProps คือมันสามารถใช้ได้ในไฟล์ _app.js ซึ่งเป็นไฟล์หลักของ Next.js ที่ใช้ควบคุมทุกหน้าในแอปของเรา

ตัวอย่างการใช้ getInitialProps ใน _app.js เพื่อดึงข้อมูล User Authentication

import App from 'next/app';

function MyApp({ Component, pageProps, user }) {
  return (
    <div>
      <p>ผู้ใช้ปัจจุบัน: {user?.name || 'Guest'}</p>
      <Component {...pageProps} />
    </div>
  );
}

MyApp.getInitialProps = async (appContext) => {
  const appProps = await App.getInitialProps(appContext);

  // สมมติว่าเราเช็ก Token และดึงข้อมูลผู้ใช้จาก API
  const user = await fetchUserFromAPI(appContext.ctx);

  return { ...appProps, user };
};

export default MyApp;

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

  • MyApp เป็นคอมโพเนนต์หลักของแอป Next.js
  • getInitialProps ถูกเรียกตอนโหลดทุกหน้า ทำให้เราสามารถดึงข้อมูลผู้ใช้และส่งไปที่ทุกเพจได้
  • ถ้าเราใช้ fetchUserFromAPI() ใน _app.js มันจะรันบน เซิร์ฟเวอร์เสมอ


📌 เมื่อไหร่ควรใช้ getInitialProps?

✅ ใช้ getInitialProps ถ้า:

  • ต้องการดึงข้อมูล ทั้งฝั่งเซิร์ฟเวอร์และไคลเอนต์
  • ต้องการดึงข้อมูลใน _app.js (แต่ปัจจุบันแนะนำให้ใช้ getServerSideProps หรือ API Context แทน)
  • ต้องการให้หน้ามี Dynamic Data แต่ไม่ต้องการใช้ SSR เต็มรูปแบบ

❌ ไม่ควรใช้ getInitialProps ถ้า:

  • หน้าเว็บไม่จำเป็นต้องโหลดข้อมูลใหม่ทุกครั้ง → ควรใช้ getStaticProps แทน
  • ต้องการโหลดเร็ว ๆ → SSR อาจช้าไป ควรใช้ CSR หรือ SSG
  • ใช้ Next.js เวอร์ชันใหม่ → Next.js แนะนำให้ใช้ getServerSideProps หรือ getStaticProps แทน


📌 เปรียบเทียบ getInitialProps vs getServerSideProps vs getStaticProps

Feature getInitialProps getServerSideProps getStaticProps
ดึงข้อมูลตอน ทุกครั้งที่โหลดหน้า (SSR) หรือเมื่อกดลิงก์ (CSR) ทุกครั้งที่โหลดหน้า (SSR) ตอน Build Time เท่านั้น (SSG)
เหมาะกับข้อมูลที่ เปลี่ยนแปลงบ่อย และต้องการทำงานทั้ง SSR + CSR เปลี่ยนแปลงบ่อย และต้องการ SSR 100% คงที่ หรือเปลี่ยนนาน ๆ ที
โหลดเร็วกว่า ❌ ช้ากว่าเพราะต้องรองรับทั้ง SSR และ CSR ❌ โหลดช้าเพราะต้องรอเซิร์ฟเวอร์ ✅ โหลดไวเพราะเป็น Static
ใช้กับ _app.js ได้ ✅ ใช้ได้ ❌ ใช้ไม่ได้ ❌ ใช้ไม่ได้
Next.js แนะนำให้ใช้? ❌ ไม่แนะนำแล้ว ✅ ใช้แทน SSR ✅ ใช้แทน SSG

💡 สรุปง่าย ๆ:

  • อย่าใช้ getInitialProps ใน Next.js เวอร์ชันใหม่ → ใช้ getServerSideProps หรือ getStaticProps แทน
  • ถ้าต้องการ SSR ใช้ getServerSideProps
  • ถ้าต้องการ Static Site ใช้ getStaticProps


📌 สรุป

getInitialProps เคยเป็นฟีเจอร์ที่ได้รับความนิยมใน Next.js แต่ปัจจุบัน Next.js แนะนำให้ใช้ SSR (getServerSideProps) หรือ SSG (getStaticProps) แทน เพราะมันแยกหน้าที่กันชัดเจนกว่าและทำให้การโหลดเว็บเร็วขึ้น

ถ้าคุณยังใช้ getInitialProps อยู่ในโปรเจ็กต์เก่า ลองเปลี่ยนมาใช้ getServerSideProps หรือ getStaticProps ดู แล้วคุณจะเห็นความแตกต่าง! 🚀

วันพุธที่ 26 กุมภาพันธ์ พ.ศ. 2568

การใช้ getServerSideProps สำหรับ Server-side Rendering (SSR)

ถ้าพูดถึงการโหลดข้อมูลแบบเรียลไทม์ และต้องการให้เซิร์ฟเวอร์เป็นคนจัดการข้อมูลทุกครั้งที่มีการรีเควสต์ หน้าเว็บของคุณต้องใช้ Server-side Rendering (SSR) และหนึ่งในฟีเจอร์เด่นของ Next.js ที่ทำให้ SSR เป็นเรื่องง่ายก็คือ getServerSideProps นั่นเอง!

วันนี้เราจะมาดูกันว่า getServerSideProps ทำงานยังไง ใช้ยังไง และเมื่อไหร่ควรใช้ พร้อมเทคนิคดี ๆ ที่จะช่วยให้คุณใช้งาน SSR ได้อย่างมีประสิทธิภาพสุด ๆ! 🚀

📌 Server-side Rendering (SSR) คืออะไร?

Server-side Rendering (SSR) คือเทคนิคที่ให้เซิร์ฟเวอร์ประมวลผลหน้าเว็บ ทุกครั้งที่มีการรีเควสต์ ซึ่งต่างจาก Static Site Generation (SSG) ที่สร้างหน้า HTML ล่วงหน้าตอน Build Time

🔍 ข้อดีของ SSR:

  • ข้อมูลอัปเดตแบบเรียลไทม์ เพราะดึงข้อมูลใหม่ทุกครั้งที่มีการโหลดหน้า
  • เหมาะกับหน้าที่ต้องการข้อมูลเฉพาะตัวของผู้ใช้ เช่น Dashboard หรือ Personalized Content
  • ไม่ต้องรอ Build ใหม่เวลาข้อมูลเปลี่ยน


❌ ข้อเสียของ SSR:

  •     โหลดช้ากว่า SSG เพราะต้องรอให้เซิร์ฟเวอร์ประมวลผลก่อน
  •     ใช้ทรัพยากรเซิร์ฟเวอร์มากขึ้น เพราะต้องประมวลผลทุกครั้งที่มีรีเควสต์
  •     แคชยากกว่า เพราะข้อมูลเปลี่ยนแปลงตลอด


📌 getServerSideProps คืออะไร?

getServerSideProps เป็นฟังก์ชันพิเศษของ Next.js ที่ใช้ดึงข้อมูลจากเซิร์ฟเวอร์แบบ Real-time ก่อนที่จะแสดงผลให้ผู้ใช้

  • เรียกใช้ ทุกครั้งที่มีการโหลดหน้า (ไม่มีการแคช)
  • ทำงานเฉพาะฝั่งเซิร์ฟเวอร์เท่านั้น (รันบน Node.js)
  • สามารถดึงข้อมูลจาก API, Database, หรือ Authentication ได้


📌 วิธีใช้ getServerSideProps

มาดูตัวอย่างกัน สมมติว่าเราต้องการดึงข้อมูลโพสต์แบบเรียลไทม์จาก API

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

  return {
    props: {
      posts,
    },
  };
}

export default function Blog({ posts }) {
  return (
    <div>
      <h1>บล็อกของเรา (SSR)</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

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

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


📌 ส่งพารามิเตอร์ไปที่ getServerSideProps

ถ้าเรามี Dynamic Routes เช่น /posts/[id] แล้วต้องการให้เซิร์ฟเวอร์ดึงข้อมูลตาม id ที่ผู้ใช้เรียก เราสามารถใช้ context.params ได้

export async function getServerSideProps(context) {
  const { id } = context.params;
  const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
  const post = await res.json();

  return {
    props: { post },
  };
}

export default function Post({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  );
}

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

  • context.params.id จะรับค่า id จาก URL
  • ดึงข้อมูลเฉพาะโพสต์ที่ตรงกับ id
  • ส่งข้อมูลไปที่ Component และแสดงผล



📌 ใช้ context เพื่อเข้าถึง Query String หรือ Headers

นอกจาก params แล้ว context ยังมีค่าที่เป็นประโยชน์อีกเพียบ เช่น

  • context.query → ใช้ดึง Query Parameters (?page=2)
  • context.req → ใช้ดึง Request Headers หรือ Session
  • context.res → ใช้เซ็ต Response Headers


ตัวอย่าง: ดึงค่าจาก Query String

export async function getServerSideProps(context) {
  const page = context.query.page || 1;
  const res = await fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}`);
  const posts = await res.json();

  return {
    props: { posts, page },
  };
}

export default function Blog({ posts, page }) {
  return (
    <div>
      <h1>บล็อก - หน้า {page}</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

✅ ข้อดี: รองรับการเปลี่ยนหน้า (?page=2) แบบเรียลไทม์!



📌 ควรใช้ getServerSideProps เมื่อไหร่?

✅ ใช้ getServerSideProps ถ้า:

  • ข้อมูลต้องอัปเดตแบบเรียลไทม์ (เช่น Dashboard, Stock Price, Weather)
  • ข้อมูลขึ้นอยู่กับผู้ใช้ (เช่น หน้า Profile, Authentication)
  • ต้องการ Query Parameters (?search=..., ?page=...)


❌ ไม่ควรใช้ getServerSideProps ถ้า:

  • ข้อมูลเปลี่ยนแปลงไม่บ่อย → ใช้ getStaticProps ดีกว่า
  • ต้องการโหลดเว็บเร็วสุด ๆ → ใช้ getStaticProps + revalidate


📌 เปรียบเทียบ getServerSideProps vs getStaticProps

Feature getServerSideProps (SSR) getStaticProps (SSG)
ดึงข้อมูลตอน ทุกครั้งที่โหลดหน้า ตอน Build Time เท่านั้น
เหมาะกับข้อมูลที่ เปลี่ยนแปลงบ่อย คงที่ หรือเปลี่ยนนาน ๆ ที
โหลดเร็วกว่า ❌ ต้องรอเซิร์ฟเวอร์ ✅ โหลดไว เพราะเป็น Static
ใช้งานร่วมกับ API ✅ ดึงข้อมูลเรียลไทม์ ✅ ดึง API ได้ตอน Build
SEO ✅ ดี ✅ ดีมาก


💡 สรุปง่าย ๆ:

  • ถ้าเป็นข้อมูลที่ไม่ค่อยเปลี่ยน ใช้ getStaticProps
  • ถ้าเป็นข้อมูลที่เปลี่ยนตลอด ใช้ getServerSideProps


📌 สรุป

getServerSideProps เป็นฟังก์ชันที่ช่วยให้ Next.js ทำ SSR ได้ง่าย ๆ โดย:

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

ถ้าเว็บของคุณต้องการโหลดข้อมูลแบบเรียลไทม์ SSR คือทางเลือกที่ใช่! 🚀

วันอังคารที่ 25 กุมภาพันธ์ พ.ศ. 2568

การใช้ getStaticProps สำหรับ Static Site Generation (SSG)

ถ้าพูดถึงการสร้างเว็บที่โหลดไว ประหยัดทรัพยากรเซิร์ฟเวอร์ และเหมาะกับ SEO สุด ๆ ก็คงหนีไม่พ้น Static Site Generation (SSG) โดยเฉพาะใน Next.js ที่มีฟีเจอร์เด็ดอย่าง getStaticProps มาช่วยดึงข้อมูลตอน Build Time ทำให้เว็บของเรากลายเป็นไฟล์ HTML ที่พร้อมเสิร์ฟทันที!

วันนี้เราจะมาเจาะลึกว่า getStaticProps ทำงานยังไง ใช้ยังไง และเมื่อไหร่ควรใช้ พร้อมทั้งแชร์ทริคเด็ด ๆ ที่จะช่วยให้คุณใช้งานมันได้อย่างมือโปร! 🚀

📌 Static Site Generation (SSG) คืออะไร?

Static Site Generation (SSG) คือเทคนิคที่เราสร้างหน้าเว็บเป็นไฟล์ HTML ล่วงหน้าตั้งแต่ตอน Build ซึ่งต่างจาก Server-Side Rendering (SSR) ที่ต้องรอให้เซิร์ฟเวอร์รันโค้ดก่อนถึงจะได้ HTML หรือ Client-Side Rendering (CSR) ที่ต้องรอให้เบราว์เซอร์โหลด JavaScript แล้วค่อยแสดงผล

พูดง่าย ๆ คือ SSG ทำให้เว็บของเรากลายเป็นไฟล์ HTML ที่พร้อมเสิร์ฟเลย ซึ่งมีข้อดีหลัก ๆ ดังนี้:

✅ โหลดไวสุด ๆ เพราะเซิร์ฟเวอร์ไม่ต้องประมวลผลเพิ่ม
✅ ลดภาระของเซิร์ฟเวอร์ เพราะทุกอย่างถูก Generate มาตั้งแต่แรก
✅ SEO ดีกว่า เพราะ Bot ของ Google อ่าน HTML ได้ทันที
✅ ใช้งานร่วมกับ CDN ได้ดี ทำให้เสิร์ฟเว็บจากตำแหน่งที่ใกล้ User ที่สุด


แต่ข้อเสียก็มีเหมือนกันนะ:

❌ ใช้ไม่ได้กับข้อมูลที่เปลี่ยนแปลงตลอดเวลา เช่น Dashboard แบบ Real-Time
❌ ถ้ามีเพจเยอะมาก ๆ การ Build อาจใช้เวลานาน

📌 getStaticProps คืออะไร?

getStaticProps เป็นฟังก์ชันของ Next.js ที่ใช้ใน Page Component เพื่อดึงข้อมูลมาตอน Build Time แล้วส่งเป็น Props ให้หน้าเว็บของเรา โดยข้อมูลที่ได้มาจะถูกแปลงเป็น HTML และใช้ซ้ำได้เรื่อย ๆ โดยไม่ต้องโหลดใหม่จากเซิร์ฟเวอร์

👉 เหมาะสำหรับหน้าเว็บที่ ใช้ข้อมูลที่ไม่เปลี่ยนบ่อย เช่น

  • บล็อกโพสต์
  • หน้า Product Catalog
  • หน้า About Us
  • รายการบทความ ฯลฯ


📌 วิธีใช้ getStaticProps

ลองมาดูตัวอย่างง่าย ๆ กัน! สมมติว่าเรามี API ที่ให้ข้อมูลเกี่ยวกับโพสต์ และเราอยากดึงมันมาตอน Build Time

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

  return {
    props: {
      posts,
    },
  };
}

export default function Blog({ posts }) {
  return (
    <div>
      <h1>บล็อกของเรา</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

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

  • getStaticProps จะถูกเรียกตอนที่เรารัน next build
  • เราใช้ fetch ดึงข้อมูลจาก API
  • ข้อมูลที่ได้จะถูกส่งไปที่ props ของคอมโพเนนต์ Blog
  • หน้าเว็บนี้จะถูก Generate เป็น HTML พร้อมข้อมูลในแต่ละโพสต์


📌 getStaticProps + getStaticPaths = Dynamic Routes!

บางครั้งเราอาจมีหน้าเว็บที่ต้องใช้ Dynamic Routes เช่น /posts/[id] แล้วเราจะให้ Next.js Generate หน้าเหล่านี้เป็น Static ได้ยังไง? ใช้ getStaticPaths ไงล่ะ!

🔥 ตัวอย่างการใช้ getStaticProps + getStaticPaths

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

  const paths = posts.map((post) => ({
    params: { id: post.id.toString() },
  }));

  return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`);
  const post = await res.json();

  return {
    props: { post },
  };
}

export default function Post({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  );
}

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

  • getStaticPaths ใช้กำหนดว่า Next.js ต้อง Generate หน้าอะไรบ้าง
  • fallback: false หมายความว่าถ้าผู้ใช้เข้าไปที่หน้า /posts/9999 ซึ่งไม่มีใน paths จะได้หน้า 404
  • getStaticProps รับ params.id แล้วไปดึงข้อมูลจาก API เพื่อส่งให้ Component


📌 revalidate - อัปเดตข้อมูลโดยไม่ต้อง Build ใหม่!

ถ้าข้อมูลของเรามีการเปลี่ยนแปลง เช่น บล็อกโพสต์ที่อัปเดตบ่อย เราสามารถใช้ revalidate เพื่อให้ Next.js รีเฟรชข้อมูลหลังจากเวลาที่กำหนด (Incremental Static Regeneration หรือ ISR)

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

  return {
    props: { posts },
    revalidate: 60, // รีเฟรชข้อมูลทุก 60 วินาที
  };
}

💡 ข้อดีของ ISR

  • ไม่ต้องรอ Build ใหม่เพื่ออัปเดตข้อมูล
  • ลดภาระของเซิร์ฟเวอร์ เพราะ Generate เฉพาะหน้าที่มีคนเข้า


📌 ควรใช้ getStaticProps เมื่อไหร่?

✅ ใช้ getStaticProps ถ้า:

  • ข้อมูลไม่เปลี่ยนแปลงบ่อย
  • ต้องการโหลดหน้าเว็บเร็วและเน้น SEO
  • ต้องการเสิร์ฟหน้าเว็บผ่าน CDN


❌ ไม่ควรใช้ getStaticProps ถ้า:

  • ข้อมูลเปลี่ยนแปลงแบบเรียลไทม์ (ใช้ Server-Side Rendering หรือ Client-Side Fetching แทน)
  • ต้องการแสดงข้อมูลที่ขึ้นอยู่กับผู้ใช้ เช่น หน้าส่วนตัว หรือแดชบอร์ด


📌 สรุป

getStaticProps เป็นเครื่องมือสุดเทพของ Next.js ที่ช่วยให้เราทำ SSG ได้ง่าย ๆ โดย:

  • ดึงข้อมูลมาตอน Build Time
  • ใช้ร่วมกับ getStaticPaths สำหรับ Dynamic Routes
  • ใช้ revalidate เพื่ออัปเดตข้อมูลโดยไม่ต้อง Build ใหม่

ใครที่อยากทำเว็บเร็ว ๆ SEO ดี ๆ ลองใช้ getStaticProps ดู รับรองว่าชีวิตง่ายขึ้นเยอะ! 🚀

วันจันทร์ที่ 24 กุมภาพันธ์ พ.ศ. 2568

ความแตกต่างระหว่าง SSR, SSG และ CSR ใน Next.js – อธิบายแบบง่ายๆ

Next.js เป็นเฟรมเวิร์กที่ทำให้การพัฒนาเว็บแอปด้วย React ง่ายและเร็วขึ้น แต่เมื่อพูดถึงการเรนเดอร์หน้าเว็บใน Next.js หลายคนอาจจะงงกับคำว่า SSR (Server-Side Rendering), SSG (Static Site Generation) และ CSR (Client-Side Rendering) ว่าแต่ละตัวต่างกันยังไง และควรเลือกใช้อะไรดี วันนี้เรามาเคลียร์ให้กระจ่าง!

🎭 อะไรคือ SSR, SSG และ CSR?

ถ้าจะเข้าใจง่าย ๆ ให้นึกถึงวิธีที่หน้าเว็บถูกโหลดขึ้นมาบนหน้าจอของผู้ใช้ มันมี 3 วิธีหลัก ๆ คือ

  • CSR (Client-Side Rendering) → โหลดหน้าเว็บแบบเปล่า ๆ แล้วให้ JavaScript ไปดึงข้อมูลมาเติมเอง
  • SSR (Server-Side Rendering) → โหลดข้อมูลที่ฝั่งเซิร์ฟเวอร์ แล้วส่ง HTML ที่มีข้อมูลมาครบให้ผู้ใช้
  • SSG (Static Site Generation) → สร้าง HTML ทั้งหมดตั้งแต่ตอน build และเสิร์ฟแบบ static


มาเจาะลึกแต่ละตัวกัน 🔍

1. CSR (Client-Side Rendering) – โหลดข้อมูลที่ฝั่งผู้ใช้

📌 มันคืออะไร?

CSR (Client-Side Rendering) เป็นแนวทางการโหลดหน้าเว็บแบบดั้งเดิมของ React คือ

  • โหลดโครงสร้างหน้าเว็บมาก่อน
  • จากนั้นใช้ JavaScript ไปดึงข้อมูลจาก API หรือ Database มาเติมที่ฝั่งผู้ใช้


🏗 ตัวอย่างโค้ด CSR ใน Next.js

import { useEffect, useState } from "react";

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

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/posts/1")
      .then((res) => res.json())
      .then((data) => setData(data));
  }, []);

  if (!data) return <p>Loading...</p>;

  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}

✅ ข้อดีของ CSR
✔️ โหลดเร็วถ้าเนื้อหาไม่เยอะ
✔️ ประสบการณ์ใช้งานลื่นไหล (เพราะไม่ต้องรีเฟรชหน้า)
✔️ ใช้งานง่ายมาก


❌ ข้อเสียของ CSR

❌ SEO ไม่ดี เพราะต้องรอให้ข้อมูลโหลดมาก่อน
❌ โหลดข้อมูลช้ากว่า เพราะต้องดึง API เพิ่ม


2. SSR (Server-Side Rendering) – เรนเดอร์บนเซิร์ฟเวอร์

📌 มันคืออะไร?

SSR (Server-Side Rendering) ทำงานตรงข้ามกับ CSR คือ

  • เมื่อมีคนเข้าเว็บ Next.js จะไปดึงข้อมูลจากเซิร์ฟเวอร์มาก่อน
  • แล้วสร้าง HTML พร้อมข้อมูล ส่งให้ผู้ใช้เลย
  • ทำให้หน้าเว็บแสดงผลพร้อมข้อมูลตั้งแต่แรก


🏗 ตัวอย่างโค้ด SSR ใน Next.js

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

  return {
    props: { data },
  };
}

export default function SSRPage({ data }) {
  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}


✅ ข้อดีของ SSR
✔️ SEO ดีมาก เพราะข้อมูลมาเป็น HTML พร้อมเลย
✔️ ใช้ได้กับเนื้อหาที่เปลี่ยนบ่อย เช่น ข่าว หรือ Dashboard
✔️ ไม่ต้องรอโหลดข้อมูลที่ฝั่งผู้ใช้


❌ ข้อเสียของ SSR
❌ โหลดช้ากว่า SSG เพราะต้องรอให้เซิร์ฟเวอร์ดึงข้อมูลก่อน
❌ ถ้ามีคนเข้าเยอะ อาจทำให้เซิร์ฟเวอร์ช้า


3. SSG (Static Site Generation) – เรนเดอร์ตั้งแต่ตอน build

📌 มันคืออะไร?

SSG (Static Site Generation) เป็นการสร้าง HTML ล่วงหน้าตั้งแต่ตอน build เวลา deploy หน้าเว็บก็จะเป็น ไฟล์ HTML Static ที่พร้อมใช้งาน

🏗 ตัวอย่างโค้ด SSG ใน Next.js

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

  return {
    props: { data },
  };
}

export default function SSGPage({ data }) {
  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}


✅ ข้อดีของ SSG
✔️ เร็วมาก เพราะหน้าเว็บถูกสร้างล่วงหน้า
✔️ รองรับ SEO ดีเยี่ยม
✔️ เซิร์ฟเวอร์ไม่ต้องทำงานหนัก


❌ ข้อเสียของ SSG
❌ ใช้กับข้อมูลที่เปลี่ยนแปลงตลอดไม่ได้ เช่น Dashboard หรือ News Feed
❌ ถ้าเปลี่ยนข้อมูล ต้อง build ใหม่


🎯 สรุปว่าเลือกอะไรดี?


วิธี โหลดเร็วไหม? 🚀 SEO ดีไหม? 🌍 เหมาะกับอะไร?
CSR (Client-Side Rendering) ปานกลาง แย่ เว็บที่ไม่เน้น SEO เช่น Dashboard
SSR (Server-Side Rendering) ช้าแต่ได้ข้อมูลครบ ดี เว็บที่มีข้อมูลเปลี่ยนบ่อย เช่น ข่าว
SSG (Static Site Generation) เร็วที่สุด ดีมาก เว็บที่ข้อมูลเปลี่ยนน้อย เช่น บล็อก


✅ แนวทางแนะนำ
  • ใช้ CSR ถ้าเน้น UX และไม่แคร์ SEO
  • ใช้ SSR ถ้าต้องอัปเดตข้อมูลบ่อย และต้องการ SEO
  • ใช้ SSG ถ้าต้องการความเร็วและ SEO ดี


🚀 Hybrid Approach – ใช้หลายแบบร่วมกัน

Next.js ไม่ได้บังคับให้ใช้แค่วิธีเดียว! เราสามารถใช้ SSR, SSG และ CSR ร่วมกันได้ เช่น

  • ใช้ SSG สำหรับหน้าเว็บหลัก เช่น หน้า About, หน้า Blog
  • ใช้ SSR สำหรับหน้าที่เปลี่ยนข้อมูลบ่อย เช่น หน้า Dashboard
  • ใช้ CSR สำหรับฟีเจอร์ที่ไม่เกี่ยวกับ SEO เช่น หน้า Chat หรือ Cart


ตัวอย่างโค้ด Hybrid Approach

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

  return {
    props: { posts },
    revalidate: 10, // อัปเดตข้อมูลทุก 10 วินาที
  };
}


🔥 สรุป

  • CSR → โหลดที่ฝั่งผู้ใช้ (เร็ว แต่ไม่ดีต่อ SEO)
  • SSR → โหลดที่ฝั่งเซิร์ฟเวอร์ (SEO ดี แต่โหลดช้ากว่า)
  • SSG → โหลดล่วงหน้าตอน build (เร็วและ SEO ดีมาก)

    Next.js ใช้หลายแบบร่วมกันได้ 🚀

วันอาทิตย์ที่ 23 กุมภาพันธ์ พ.ศ. 2568

การใช้ Tailwind CSS กับ Next.js แบบเข้าใจง่าย

Tailwind CSS เป็นหนึ่งใน CSS Framework ที่มาแรงที่สุดในตอนนี้ เพราะมันทำให้การเขียนสไตล์สะดวกขึ้นแบบสุด ๆ และใช้งานร่วมกับ Next.js ได้อย่างลงตัว วันนี้เราจะมาดูวิธีติดตั้งและใช้งาน Tailwind CSS กับ Next.js ตั้งแต่เริ่มต้นจนถึงเทคนิคการใช้งานให้โค้ดดูสะอาดขึ้น

🌟 ทำไมต้องใช้ Tailwind CSS?

Tailwind CSS ไม่เหมือน CSS Framework ทั่วไป เช่น Bootstrap ที่ให้เราสไตล์องค์ประกอบต่าง ๆ มาพร้อมใช้งานเลย แต่ Tailwind ใช้แนวคิด Utility-First หรือก็คือให้เรากำหนดสไตล์เองผ่าน class ที่เล็ก ๆ เช่น

<button class="bg-blue-500 text-white px-4 py-2 rounded">คลิกเลย!</button>

แปลว่าเราไม่ต้องสร้างไฟล์ CSS แยก ไม่ต้องคิดชื่อ class เอง แค่ใช้ class ที่มีมาให้ก็พอ! 🎉

🛠 วิธีติดตั้ง Tailwind CSS ใน Next.js

1. เปิด terminal แล้วรันคำสั่งติดตั้ง

npx create-next-app@latest my-tailwind-app
cd my-tailwind-app

2. ติดตั้ง Tailwind CSS และแพ็กเกจที่เกี่ยวข้อง

npm install -D tailwindcss postcss autoprefixer

3. สร้างไฟล์ tailwind.config.js

npx tailwindcss init -p

4. แก้ไข tailwind.config.js เพื่อให้ Tailwind ทำงานกับไฟล์ Next.js

module.exports = {
  content: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

5. นำเข้า Tailwind CSS ในไฟล์ styles/globals.css

@tailwind base;
@tailwind components;
@tailwind utilities;

6. ลองรันเซิร์ฟเวอร์ดู! 🚀

    npm run dev


🎨 เริ่มใช้งาน Tailwind CSS ใน Next.js

ตัวอย่างการใช้งานเบื้องต้น

เปิด pages/index.js แล้วลองใช้ Tailwind CSS

export default function Home() {
  return (
    <div className="min-h-screen flex items-center justify-center bg-gray-100">
      <h1 className="text-4xl font-bold text-blue-600">สวัสดี Tailwind CSS + Next.js!</h1>
    </div>
  );
}

🔥 สไตล์ที่ใช้ไปมีอะไรบ้าง?

  • min-h-screen → ให้ความสูงเต็มหน้าจอ
  • flex items-center justify-center → จัดให้อยู่ตรงกลาง
  • bg-gray-100 → พื้นหลังสีเทาอ่อน
  • text-4xl → ขนาดตัวอักษรใหญ่
  • font-bold → ตัวหนา
  • text-blue-600 → สีตัวอักษรฟ้า

ง่ายและเร็วมาก! 😍


🛠 เทคนิคการใช้งาน Tailwind CSS ให้โค้ดสะอาดขึ้น

✨ ใช้ @apply ในไฟล์ CSS

ถ้า class มันเยอะไป เราสามารถใช้ @apply เพื่อรวม class ใน globals.css ได้

/* styles/globals.css */
.btn {
  @apply bg-blue-500 text-white px-4 py-2 rounded shadow-md hover:bg-blue-600;
}

แล้วใช้ใน JSX แบบนี้

<button className="btn">กดเลย!</button>


📌 ใช้ classnames เพื่อจัดการ class ที่ซับซ้อน

ถ้ามีเงื่อนไขว่า class ไหนต้องแสดงหรือไม่แสดง ลองใช้ไลบรารี classnames

npm install classnames

จากนั้นใช้แบบนี้

import classNames from "classnames";

function Button({ primary }) {
  return (
    <button
      className={classNames(
        "px-4 py-2 rounded",
        primary ? "bg-blue-500 text-white" : "bg-gray-300 text-black"
      )}
    >
      กดเลย!
    </button>
  );
}

⚡️ ใช้ Tailwind CSS กับ Components ใน Next.js

สร้างคอมโพเนนต์ปุ่ม

สร้างไฟล์ components/Button.js

export default function Button({ children }) {
  return (
    <button className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600">
      {children}
    </button>
  );
}

แล้วใช้ใน index.js

import Button from "../components/Button";

export default function Home() {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <Button>คลิกฉัน!</Button>
    </div>
  );
}

🚀 ใช้ Tailwind CSS กับ Dark Mode

Tailwind รองรับ Dark Mode ได้ง่ายมาก แค่เพิ่ม dark: ข้างหน้าคลาส

<div className="bg-white dark:bg-gray-800 text-black dark:text-white">
  โหมดมืดจ้า!
</div>

แต่ต้องไปแก้ tailwind.config.js นิดหน่อย

module.exports = {
  darkMode: "class", // เปิดใช้ dark mode แบบ manual
  content: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

แล้วใช้ JavaScript เปลี่ยนโหมด

import { useEffect, useState } from "react";

export default function Home() {
  const [darkMode, setDarkMode] = useState(false);

  useEffect(() => {
    document.documentElement.classList.toggle("dark", darkMode);
  }, [darkMode]);

  return (
    <div className="min-h-screen flex flex-col items-center justify-center">
      <button onClick={() => setDarkMode(!darkMode)} className="px-4 py-2 bg-blue-500 text-white rounded">
        เปลี่ยนโหมด
      </button>
    </div>
  );
}

🎯 Tailwind CSS กับ Next.js ทำอะไรได้อีก?

  • ใช้ Animations & Transitions เช่น animate-bounce
  • ใช้ Responsive Design ง่าย ๆ เช่น md:bg-red-500
  • ใช้ Grid & Flexbox ได้แบบสะดวกสุด ๆ
  • ใช้ Custom Theme ปรับแต่งสีหรือฟอนต์ใน tailwind.config.js


🔥 สรุป

  • Tailwind CSS ใช้งานง่ายและเร็วมากใน Next.js
  • ติดตั้งง่ายแค่ npm install tailwindcss
  • ใช้ class utility ได้เลย ไม่ต้องเขียน CSS แยก
  • ปรับแต่งธีมเองได้ และรองรับ Dark Mode
  • ใช้ร่วมกับ classnames หรือ @apply ให้โค้ดสะอาดขึ้น

ถ้าคุณยังไม่เคยลอง Tailwind CSS กับ Next.js นี่เป็นเวลาที่เหมาะสุด ๆ แล้ว! 🚀

วันเสาร์ที่ 22 กุมภาพันธ์ พ.ศ. 2568

การใช้ CSS ใน Next.js (CSS Modules และ Global CSS)

Next.js เป็นหนึ่งในเฟรมเวิร์กยอดฮิตสำหรับการสร้างเว็บแอปพลิเคชันด้วย React ซึ่งแน่นอนว่าเรื่องของการสไตลิ่ง (styling) ก็เป็นส่วนสำคัญที่เราต้องจัดการให้ดี ใน Next.js เรามีหลายทางเลือกในการใช้ CSS และที่นิยมกันมากคือ CSS Modules และ Global CSS วันนี้เราจะมาทำความเข้าใจทั้งสองแนวทางนี้กันแบบเข้าใจง่าย ๆ

🌍 Global CSS: สไตล์แบบจัดเต็มทั้งเว็บ

Global CSS คือการใช้ไฟล์ CSS ทั่วไปที่เราคุ้นเคยกันดี เหมือนที่ใช้ใน HTML หรือ React ปกติ วิธีนี้เหมาะกับการกำหนดสไตล์ที่ใช้ซ้ำกันทั้งเว็บ เช่น ฟอนต์ พื้นหลัง หรือธีมหลัก

🛠 วิธีใช้ Global CSS ใน Next.js

1. สร้างไฟล์ CSS
    โดยทั่วไป เราจะเก็บไฟล์ Global CSS ไว้ที่ styles/global.css

2. นำเข้าใน _app.js หรือ _app.tsx
    _app.js เป็นไฟล์หลักที่ใช้ควบคุมแอปทั้งหมด ดังนั้นถ้าเราต้องการให้ Global CSS ใช้งานได้ทุกหน้าก็ต้อง import เข้าไปในไฟล์นี้

import '../styles/global.css';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;

3. ใช้งานได้เลย!
    ตอนนี้เราสามารถเขียน CSS ตามปกติใน global.css ได้ เช่น

    body {
      font-family: 'Arial', sans-serif;
      background-color: #f5f5f5;
    }

    h1 {
      color: blue;
    }

❌ ข้อควรระวัง

  • Global CSS มีผลต่อทุกหน้า
  • ถ้าเผลอไปกำหนดสไตล์ผิด ๆ อาจจะพังทั้งเว็บ!
  • ไม่สามารถใช้ CSS Modules ใน _app.js ได้
  • Next.js ไม่อนุญาตให้ import CSS Modules ใน _app.js ต้องใช้ Global CSS เท่านั้น


🎯 CSS Modules: สไตล์แบบแยกเฉพาะตัว

CSS Modules เป็นเทคนิคที่ทำให้ CSS มีขอบเขตเฉพาะคอมโพเนนต์ ไม่ต้องกลัวปัญหา CSS ซ้อนทับกัน หรือไปยุ่งกับสไตล์ของส่วนอื่นในเว็บ

🛠 วิธีใช้ CSS Modules ใน Next.js

1. สร้างไฟล์ CSS Modules
    ไฟล์ CSS Modules จะต้องลงท้ายด้วย .module.css เช่น styles/Button.module.css

2. นำเข้าในคอมโพเนนต์

import styles from '../styles/Button.module.css';

function Button() {
  return <button className={styles.button}>คลิกเลย!</button>;
}

export default Button;

3. เขียนสไตล์ในไฟล์ CSS Modules

    /* styles/Button.module.css */
    .button {
      background-color: #ff6347;
      color: white;
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }

✅ ข้อดีของ CSS Modules

  • ไม่มีปัญหา CSS ซ้อนทับกัน เพราะทุกคลาสจะถูกทำให้มีชื่อเฉพาะตัว เช่น Button_button__3fXj9
  • แยกสไตล์แต่ละคอมโพเนนต์ได้ง่าย ทำให้โค้ดดูแลรักษาง่ายขึ้น
  • สามารถใช้ร่วมกับ SCSS ได้ ถ้าต้องการใช้ SCSS ก็แค่เปลี่ยนนามสกุลไฟล์เป็น .module.scss แล้วติดตั้ง sass

    npm install sass


🤔 เลือกใช้ Global CSS หรือ CSS Modules ดี?

วิธี ข้อดี ข้อเสีย
Global CSS ใช้งานง่าย, ใช้กับธีมและสไตล์ทั่วเว็บได้ อาจเกิดปัญหา CSS ซ้อนกัน
CSS Modules ป้องกัน CSS ทับกัน, เหมาะกับคอมโพเนนต์แยกกัน ใช้กับ _app.js ไม่ได้

🔥 ใช้ร่วมกันได้!

จริง ๆ แล้ว เราสามารถใช้ Global CSS สำหรับธีมหลัก และใช้ CSS Modules สำหรับคอมโพเนนต์เฉพาะตัวได้ โดยไม่ต้องเลือกอย่างใดอย่างหนึ่ง


💡 เทคนิคน่าสนใจ

ใช้ CSS Modules ร่วมกับ classnames

ถ้าอยากใช้หลายคลาสพร้อมกันใน CSS Modules ลองใช้ไลบรารี classnames

npm install classnames

แล้วใช้แบบนี้ในคอมโพเนนต์:

import styles from '../styles/Card.module.css';
import classNames from 'classnames';

function Card({ highlighted }) {
  return (
    <div className={classNames(styles.card, { [styles.highlighted]: highlighted })}>
      นี่คือการ์ด!
    </div>
  );
}

export default Card;

/* styles/Card.module.css */
.card {
  padding: 20px;
  border: 1px solid #ddd;
}

.highlighted {
  background-color: yellow;
}


🔥 สรุป

  • Global CSS ใช้สำหรับธีมหลักของเว็บ
  • CSS Modules เหมาะกับสไตล์ที่ต้องการแยกเฉพาะคอมโพเนนต์
  • สามารถใช้ Global CSS และ CSS Modules ร่วมกันได้
  • ถ้าต้องการใช้หลายคลาสใน CSS Modules ให้ใช้ classnames

หวังว่าบทความนี้จะช่วยให้คุณเข้าใจการใช้ CSS ใน Next.js ได้ง่ายขึ้นนะ! 🚀

วันศุกร์ที่ 21 กุมภาพันธ์ พ.ศ. 2568

การสร้าง Component และการนำไปใช้ใน Next.js

ถ้าคุณเป็นสาย React และกำลังใช้ Next.js เพื่อสร้างเว็บแอป คุณอาจสงสัยว่า "การสร้าง Component และนำไปใช้ใน Next.js ต่างจาก React ปกติยังไง?"

จริง ๆ แล้วหลักการสร้าง Component ใน Next.js ก็คล้ายกับ React ทั่วไป แต่ Next.js มีฟีเจอร์พิเศษบางอย่างที่ช่วยให้การจัดการ Component มีประสิทธิภาพขึ้น

บทความนี้จะพาคุณไปดูทุกมุมของการสร้าง Component ตั้งแต่พื้นฐาน ไปจนถึงแนวทางปฏิบัติที่ดี เพื่อให้คุณสามารถ เขียนโค้ดที่เป็นระเบียบ ใช้ซ้ำได้ และโหลดเร็วขึ้น

Component คืออะไร?

Component เป็นส่วนย่อยของ UI ที่สามารถนำมาใช้ซ้ำได้ ตัวอย่างเช่น

  • ปุ่ม (Button)
  • แถบนำทาง (Navbar)
  • การ์ดแสดงข้อมูล (Card)
  • กล่องข้อความ (Input field)

แทนที่เราจะเขียนโค้ดซ้ำ ๆ ทุกหน้า เราสามารถสร้าง Component และนำไปใช้ซ้ำได้ทั่วทั้งเว็บ

1. การสร้าง Component ใน Next.js

1.1 การสร้าง Component แบบพื้นฐาน

ใน Next.js ไฟล์ Component ควรเก็บไว้ในโฟลเดอร์ components/ เพื่อให้โครงสร้างโปรเจกต์ดูเป็นระเบียบ

ตัวอย่างการสร้าง Component Button.js

export default function Button({ text }) {
  return <button className="btn">{text}</button>;
}


Note:

  • เราส่งค่า text ผ่าน Props เพื่อให้ปุ่มนี้สามารถแสดงข้อความที่แตกต่างกันได้
  • ควรตั้งชื่อไฟล์เป็น ตัวพิมพ์ใหญ่ เช่น Button.js ตามหลักการตั้งชื่อ Component

 

1.2 การใช้ Component ในหน้า Next.js

เมื่อสร้าง Component แล้ว เราสามารถ import และใช้มันในไฟล์อื่น ได้ เช่นใน pages/index.js

ใช้ Button ในหน้า index.js

import Button from '../components/Button';

export default function Home() {
  return (
    <div>
      <h1>Welcome to Next.js 🚀</h1>
      <Button text="คลิกเลย!" />
      <Button text="สมัครสมาชิก" />
    </div>
  );
}

✅ ผลลัพธ์ที่ได้:

Welcome to Next.js 🚀  
[ คลิกเลย! ]  [ สมัครสมาชิก ]

1.3 การส่งค่า Props ไปยัง Component

Props เป็นค่าที่ส่งจาก Parent Component ไปยัง Child Component
ทำให้เราสามารถปรับแต่ง Component ได้ง่ายขึ้น

ตัวอย่าง Component Card.js รับค่า Props

export default function Card({ title, description }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <p>{description}</p>
    </div>
  );
}


การใช้ Card ใน index.js


import Card from '../components/Card';

export default function Home() {
  return (
    <div>
      <h1>รายการบทความ</h1>
      <Card title="Next.js คืออะไร?" description="Next.js เป็น React Framework ที่ได้รับความนิยมมาก" />
      <Card title="การใช้ API Routes" description="API Routes ช่วยให้เราสร้าง Backend ใน Next.js ได้ง่าย" />
    </div>
  );
}


✅ ผลลัพธ์ที่ได้:

รายการบทความ  
----------------  
Next.js คืออะไร?  
Next.js เป็น React Framework ที่ได้รับความนิยมมาก  

การใช้ API Routes  
API Routes ช่วยให้เราสร้าง Backend ใน Next.js ได้ง่าย  


สังเกต:

  • เราสามารถใช้ Card ได้หลายครั้งโดยเปลี่ยนค่า Props
  • ทำให้โค้ดดูสะอาด และจัดการง่ายขึ้น


2. การจัดการ Layout ด้วย Component

Next.js มีไฟล์ _app.js ซึ่งช่วยให้เราสร้าง Layout ที่ใช้ซ้ำกันทุกหน้า ได้ง่ายขึ้น

2.1 สร้าง Layout Component

ไฟล์ components/Layout.js

export default function Layout({ children }) {
  return (
    <div>
      <header>🔥 My Website</header>
      <main>{children}</main>
      <footer>⚡ Powered by Next.js</footer>
    </div>
  );
}


2.2 ใช้ Layout ใน _app.js

import Layout from '../components/Layout';
import '../styles/globals.css';

export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

✅ ผลลัพธ์ที่ได้

  • ทุกหน้าจะมี Header และ Footer โดยอัตโนมัติ



3. การใช้ CSS ใน Component

Next.js รองรับการใช้ CSS ได้หลายแบบ เช่น

  •     Global CSS (styles/globals.css)
  •     Module CSS (.module.css)
  •     Styled Components


3.1 ใช้ Global CSS

ไฟล์: styles/globals.css

.btn {
  background-color: blue;
  color: white;
  padding: 10px 20px;
  border: none;
  cursor: pointer;
}

ไฟล์: components/Button.js

import '../styles/globals.css';

export default function Button({ text }) {
  return <button className="btn">{text}</button>;
}


✅ ข้อดีของ Global CSS

  •     ใช้งานง่าย และใช้ได้กับทุก Component


3.2 ใช้ Module CSS (แนะนำ)

ไฟล์: components/Button.module.css

.btn {
  background-color: red;
  color: white;
  padding: 10px 20px;
  border: none;
  cursor: pointer;
}

ไฟล์: components/Button.js

import styles from './Button.module.css';

export default function Button({ text }) {
  return <button className={styles.btn}>{text}</button>;
}


✅ ข้อดีของ Module CSS

  • ป้องกันการชนกันของ CSS
  • ทำให้โค้ดเป็นระเบียบ

สรุป

หัวข้อวิธีใช้งาน
สร้าง Componentใช้ Function Component (export default function Component() {})
ใช้ Componentimport Component from '../components/Component'
ส่งค่าเข้า Componentใช้ Props (<Component name="John" />)
ใช้ Layout ซ้ำกันทุกหน้าใช้ _app.js และ Layout Component
ใช้ CSS ใน Componentใช้ Global CSS หรือ Module CSS


ข้อดีของการใช้ Component ใน Next.js
✅ โค้ดสะอาดขึ้น
✅ ใช้ซ้ำได้
✅ โหลดเร็วขึ้น (Static Optimization)

วันพฤหัสบดีที่ 20 กุมภาพันธ์ พ.ศ. 2568

การจัดการ Layout ด้วย _app.js และ _document.js ใน Next.js

ถ้าคุณเคยเขียนเว็บแอปด้วย Next.js แล้วต้องการให้ทุกหน้ามีโครงสร้าง Layout เหมือนกัน เช่น มี Header, Footer, หรือใช้ธีมเดียวกัน คุณอาจจะเจอปัญหาว่า "ฉันต้องคัดลอกโค้ดพวกนี้ไปทุกหน้าเลยเหรอ?"

ข่าวดีคือ Next.js มีไฟล์พิเศษ _app.js และ _document.js ที่ช่วยให้เราจัดการ Layout และโครงสร้างเอกสาร HTML ได้ง่ายขึ้น!

ในบทความนี้ เราจะมาทำความเข้าใจว่า _app.js และ _document.js คืออะไร ใช้งานยังไง และมีเทคนิคอะไรที่ช่วยให้เว็บเราทำงานได้ดีขึ้น พร้อมตัวอย่างโค้ดแบบเข้าใจง่าย


 _app.js และ _document.js คืออะไร?


📌 _app.js (หรือ _app.tsx สำหรับ TypeScript)
  • เป็นไฟล์ที่ทำหน้าที่ ครอบทุกหน้าในเว็บของเรา
  • ใช้สำหรับ จัดการ Layout เช่น ใส่ Header, Footer, Theme, Global CSS
  • ใช้เพื่อ ควบคุม state ของแอป เช่น Redux, Context API

📌 _document.js
  • ใช้เพื่อกำหนด โครงสร้าง HTML พื้นฐาน ของเว็บ
  • ใช้ใส่พวก Meta tags, Font, Script ที่ต้องโหลดก่อนหน้าเว็บ
  • ใช้แก้ไข <html>, <head>, <body> ที่ Next.js สร้างขึ้นอัตโนมัติ

1. _app.js – ควบคุม Layout ของเว็บ

โค้ดตัวอย่าง _app.js

import '../styles/globals.css';

export default function MyApp({ Component, pageProps }) {
  return (
    <div>
      <header>My Header</header>
      <main>
        <Component {...pageProps} />
      </main>
      <footer>My Footer</footer>
    </div>
  );
}


อธิบายโค้ด

  • Component คือหน้าที่เรากำลังเข้าถึง เช่น /about หรือ /contact
  • pageProps คือข้อมูลที่ถูกส่งไปยังหน้านั้น ๆ
  • <header> และ <footer> จะอยู่เหมือนกันทุกหน้า


✅ ข้อดีของการใช้ _app.js

  • ทำให้ทุกหน้ามี Layout เหมือนกัน
  • ลดโค้ดซ้ำซ้อน ไม่ต้องใส่ <header> หรือ <footer> เองทุกหน้า


2. ใช้ Layout แยกตามหน้า

บางหน้าของเว็บอาจต้องการ Layout ที่แตกต่างกัน เช่น หน้า Dashboard กับหน้า Landing Page อาจใช้ Layout คนละแบบ
 

วิธีใช้ Layout แบบกำหนดเอง

export default function MyApp({ Component, pageProps }) {
  const getLayout = Component.getLayout || ((page) => page);

  return getLayout(<Component {...pageProps} />);
}

จากนั้นที่หน้าไหนที่ต้องการ Layout พิเศษ ให้เพิ่มฟังก์ชัน getLayout

import DashboardLayout from '../components/DashboardLayout';

export default function Dashboard() {
  return <h1>This is Dashboard</h1>;
}

Dashboard.getLayout = function getLayout(page) {
  return <DashboardLayout>{page}</DashboardLayout>;
};


✅ ข้อดีของวิธีนี้

  • ทำให้แต่ละหน้าสามารถใช้ Layout ที่แตกต่างกันได้
  • ไม่ต้องใช้เงื่อนไข if ใน _app.js ให้ยุ่งยาก


3. _document.js – ควบคุมโครงสร้าง HTML

ปกติแล้ว Next.js สร้างโครงสร้าง HTML อัตโนมัติให้ แต่ถ้าเราต้องการเพิ่ม Meta Tags, Font, หรือแก้ไข <html> และ <body> เราต้องใช้ _document.js
 

โค้ดตัวอย่าง _document.js

import { Html, Head, Main, NextScript } from 'next/document';

export default function MyDocument() {
  return (
    <Html lang="th">
      <Head>
        <meta charSet="UTF-8" />
        <meta name="description" content="This is my Next.js app" />
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link
          href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap"
          rel="stylesheet"
        />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}


อธิบายโค้ด

  • <Html lang="th"> → กำหนดภาษาเริ่มต้นเป็นภาษาไทย
  • <meta> → ใส่ข้อมูลเกี่ยวกับเว็บ เช่น คำอธิบาย
  • <link> → ใส่ฟอนต์จาก Google Fonts
  • <Main /> → ตรงนี้คือเนื้อหาของแต่ละหน้า
  • <NextScript /> → ใส่สคริปต์ที่ Next.js ต้องการ


✅ ข้อดีของการใช้ _document.js

  • กำหนดค่า <html> และ <body> ได้
  • ใส่ Global Meta Tags ได้ง่ายขึ้น
  • ทำให้เว็บโหลดเร็วขึ้น (ใช้ preconnect, preload)


4. ใช้ _app.js และ _document.js ร่วมกันให้เกิดประโยชน์สูงสุด

ลองดูโค้ดตัวอย่างที่ผสมทั้ง _app.js และ _document.js ให้ทำงานร่วมกัน

 _app.js

import '../styles/globals.css';
import Layout from '../components/Layout';

export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}


_document.js

import { Html, Head, Main, NextScript } from 'next/document';

export default function MyDocument() {
  return (
    <Html lang="en">
      <Head>
        <meta charSet="UTF-8" />
        <link rel="stylesheet" href="/global.css" />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}


✅ ผลลัพธ์ที่ได้

  • ทุกหน้าจะถูกครอบด้วย <Layout> ที่เราสร้าง
  • Meta Tags และ Font ถูกใส่จาก _document.js
  • โค้ดสะอาดและเป็นระเบียบ


สรุป

ความสามารถ_app.js_document.js
ควบคุม Layout✅❌
ใส่ Meta Tags❌✅
ใส่ CSS/Theme✅✅
ใส่ Script พิเศษ❌✅
แก้ไข <html> และ <body>❌✅

  • _app.js ใช้สำหรับควบคุม Layout และการทำงานของแอป
  • _document.js ใช้สำหรับกำหนดโครงสร้าง HTML และ Meta Tags

ถ้าคุณใช้งานทั้งสองไฟล์ให้ถูกวิธี เว็บของคุณจะเร็วขึ้น โหลดเร็วขึ้น และจัดการง่ายขึ้นแน่นอน!

วันพุธที่ 19 กุมภาพันธ์ พ.ศ. 2568

การใช้ Link และ useRouter เพื่อการนำทางใน Next.js

การนำทาง (Navigation) เป็นหนึ่งในองค์ประกอบสำคัญของเว็บแอปพลิเคชัน เพราะมันทำให้ผู้ใช้สามารถเคลื่อนที่ไปมาระหว่างหน้าได้อย่างราบรื่น ใน Next.js ซึ่งเป็น React Framework ที่ได้รับความนิยมสูง เรามีเครื่องมือสองตัวที่ใช้ในการนำทางหลัก ๆ ได้แก่ Link และ useRouter

ในบทความนี้ เราจะมาทำความเข้าใจว่า Link และ useRouter คืออะไร ใช้งานยังไง และมีกรณีไหนบ้างที่ควรใช้ตัวไหน พร้อมตัวอย่างโค้ดที่เข้าใจง่าย


ทำไมต้องใช้ Link และ useRouter?

ใน Next.js เราสามารถใช้ <a href="..."> แบบปกติได้ แต่ปัญหาคือมันจะโหลดหน้าใหม่ทุกครั้งที่คลิกลิงก์ ซึ่งไม่ใช่สิ่งที่เราต้องการสำหรับเว็บแอปที่ต้องการความเร็วและประสิทธิภาพสูง

Link และ useRouter แก้ปัญหานี้ได้อย่างไร?

  • Link ช่วยให้เราสามารถทำ client-side navigation ได้โดยที่ไม่ต้องโหลดหน้าใหม่
  • useRouter ให้เราควบคุมการนำทางด้วยโค้ด เช่น การเปลี่ยนเส้นทาง (redirect) หรือดึงค่าพารามิเตอร์จาก URL


1. Link – วิธีสร้างลิงก์นำทางแบบง่าย ๆ

ถ้าเราต้องการสร้างลิงก์ระหว่างหน้าต่าง ๆ ใน Next.js วิธีที่ถูกต้องคือใช้ <Link> จาก next/link

ตัวอย่างการใช้งานพื้นฐาน

import Link from 'next/link';

export default function Home() {
  return (
    <div>
      <h1>หน้าแรก</h1>
      <Link href="/about">ไปที่หน้า About</Link>
    </div>
  );
}


✅ ทำไมต้องใช้ Link แทน <a>?

  • เมื่อใช้ Link Next.js จะ โหลดหน้าใหม่ให้เร็วขึ้น เพราะมันใช้เทคนิคการ prefetch (โหลดล่วงหน้า)
  • ไม่ต้องโหลด HTML ใหม่ทั้งหน้า เหมือนกับ Single Page Application (SPA)
  • การใช้งานง่าย ไม่ต้องเขียนโค้ด JavaScript เพิ่ม


2. useRouter – การควบคุมเส้นทางด้วย JavaScript

ในบางกรณี เราอาจต้องนำทางโดยไม่ใช้ <Link> เช่น การเปลี่ยนหน้าเมื่อผู้ใช้กดปุ่ม หรือเปลี่ยนเส้นทางหลังจากทำบางอย่างเสร็จ (redirect)

Next.js มี useRouter จาก next/router ที่ช่วยให้เราควบคุมเส้นทางได้ผ่านโค้ด JavaScript

ตัวอย่างการใช้งาน useRouter เพื่อเปลี่ยนหน้า

import { useRouter } from 'next/router';

export default function Home() {
  const router = useRouter();

  const goToAbout = () => {
    router.push('/about');
  };

  return (
    <div>
      <h1>หน้าแรก</h1>
      <button onClick={goToAbout}>ไปที่หน้า About</button>
    </div>
  );
}


✅ router.push(url) ทำอะไรได้บ้าง?

  • เปลี่ยนเส้นทางโดยไม่ต้องใช้ <Link>
  • ทำให้การเปลี่ยนหน้าเกิดขึ้นจากอีเวนต์ เช่น คลิกปุ่ม หรือส่งฟอร์ม
  • รองรับการใช้พารามิเตอร์ใน URL



3. ส่งค่าผ่าน URL ด้วย Query Parameters

ในบางกรณี เราอาจต้องส่งข้อมูลไปพร้อมกับ URL เช่น /profile?user=JohnDoe

วิธีส่งค่าไปยังหน้าอื่น

import { useRouter } from 'next/router';

export default function Home() {
  const router = useRouter();

  const goToProfile = () => {
    router.push({
      pathname: '/profile',
      query: { user: 'JohnDoe' },
    });
  };

  return (
    <div>
      <h1>หน้าแรก</h1>
      <button onClick={goToProfile}>ไปที่โปรไฟล์ของ John Doe</button>
    </div>
  );
}


4. ดึงค่าพารามิเตอร์จาก URL

เมื่อเราส่งค่าไปกับ URL แล้ว เราก็ต้องดึงค่ามาใช้ที่หน้าปลายทาง

วิธีดึงค่าจาก query parameters

import { useRouter } from 'next/router';

export default function Profile() {
  const router = useRouter();
  const { user } = router.query; // ดึงค่าพารามิเตอร์จาก URL

  return (
    <div>
      <h1>โปรไฟล์ของ {user || 'ไม่ทราบชื่อ'}</h1>
    </div>
  );
}

✅ จุดที่ต้องระวัง

  • ค่า router.query อาจเป็น undefined ถ้าหน้าโหลดครั้งแรก ต้องเช็กก่อนใช้


5. นำทางแบบ Dynamic Routing

ถ้าเรามีเส้นทางแบบไดนามิก เช่น /blog/[id] และอยากเปลี่ยนหน้าไปที่ /blog/123 เราสามารถใช้ router.push() ได้แบบนี้

ตัวอย่าง Dynamic Routing

import { useRouter } from 'next/router';

export default function BlogList() {
  const router = useRouter();

  const goToBlog = (id) => {
    router.push(`/blog/${id}`);
  };

  return (
    <div>
      <h1>รายการบทความ</h1>
      <button onClick={() => goToBlog(123)}>อ่านบทความ 123</button>
    </div>
  );
}

ที่หน้า /blog/[id].js เราสามารถดึงค่า id จาก URL ได้แบบนี้

import { useRouter } from 'next/router';

export default function BlogPost() {
  const router = useRouter();
  const { id } = router.query;

  return <h1>บทความที่ {id}</h1>;
}


Link กับ useRouter ควรใช้เมื่อไหร่?

กรณี                                                ใช้ Link    ใช้ useRouter
ลิงก์ระหว่างหน้า                                    ✅              ❌
นำทางจากปุ่มหรืออีเวนต์                      ❌              ✅
ส่งค่าไปกับ URL                                   ❌              ✅
Redirect หลังทำบางอย่างเสร็จ             ❌              ✅
ต้องการโหลดล่วงหน้า (prefetch)          ✅             ❌


สรุป

  • Link ใช้สำหรับการนำทางแบบปกติที่ต้องการให้ Next.js จัดการ prefetch ให้
  • useRouter ใช้เมื่อต้องการนำทางด้วยโค้ด JavaScript เช่น การ redirect หรือดึงค่าจาก URL
  • Next.js ช่วยให้การนำทางรวดเร็วและมีประสิทธิภาพกว่าการใช้ <a> แบบดั้งเดิม

หวังว่าบทความนี้จะช่วยให้คุณเข้าใจการนำทางใน Next.js มากขึ้น!

วันอังคารที่ 18 กุมภาพันธ์ พ.ศ. 2568

การใช้งาน pages/ และการสร้าง Routing อัตโนมัติใน Next.js

ถ้าคุณเป็นสายเว็บที่อยากเขียนเว็บเร็ว ๆ ไม่ต้องมานั่งเซ็ต Routing เองให้ปวดหัว Next.js คือเพื่อนที่คุณต้องการ! หนึ่งในฟีเจอร์เด็ดของมันคือการใช้โฟลเดอร์ pages/ เพื่อสร้าง Routing แบบอัตโนมัติ ที่จะทำให้ชีวิตของคุณง่ายขึ้น ไม่ต้องมานั่งเขียนไฟล์ routes.js หรือกำหนด path เองแบบสมัยก่อน

บทความนี้จะพาคุณไปทำความเข้าใจว่า โฟลเดอร์ pages/ ใน Next.js ทำงานยังไง, จะใช้มันให้เกิดประโยชน์สูงสุดได้ยังไง, และ ถ้าคุณอยากใช้ Dynamic Routing หรือ API Routes ต้องทำยังไง มาเริ่มกันเลย!

 

พื้นฐานของโฟลเดอร์ pages/

ใน Next.js โฟลเดอร์ pages/ เป็นศูนย์กลางของระบบ Routing ทั้งหมด มันทำงานง่าย ๆ คือ "มีไฟล์อะไรใน pages/ ก็จะมี URL ตามไฟล์นั้น" เช่น

  • pages/index.js → /
  • pages/about.js → /about
  • pages/contact.js → /contact

แค่สร้างไฟล์ .js หรือ .tsx ในโฟลเดอร์นี้ Next.js ก็จะสร้างเส้นทางให้โดยอัตโนมัติ ไม่ต้องเขียนโค้ดอะไรเพิ่ม!

ตัวอย่างไฟล์ pages/about.js 

export default function AboutPage() {
  return <h1>นี่คือหน้า About</h1>;
}

พอสร้างไฟล์นี้เสร็จ คุณสามารถเข้าเว็บที่ /about ได้เลยโดยไม่ต้องตั้งค่าอะไรเพิ่ม!


สร้าง Routing อัตโนมัติแบบง่าย ๆ

การสร้างหน้าใหม่

ถ้าอยากเพิ่มหน้าใหม่ ก็แค่สร้างไฟล์ใหม่ใน pages/ เท่านั้น เช่น

mkdir pages/blog
touch pages/blog/index.js

จากนั้นเพิ่มโค้ดง่าย ๆ

export default function BlogPage() {
  return <h1>ยินดีต้อนรับสู่หน้า Blog!</h1>;
}

แค่นี้คุณก็สามารถเข้าหน้า /blog ได้แล้ว ไม่ต้องไปแก้ไขอะไรเพิ่มเติมเลย 

 

Dynamic Routing: เส้นทางที่ยืดหยุ่นกว่านี้มีอีกไหม? มี!

สมมติว่าคุณอยากสร้างหน้า Blog ที่สามารถรองรับโพสต์หลาย ๆ อัน เช่น /blog/post-1, /blog/post-2 โดยไม่ต้องสร้างไฟล์ใหม่ให้แต่ละโพสต์เอง เราสามารถใช้ Dynamic Routing ได้โดยใช้เครื่องหมาย [] ในชื่อไฟล์

ตัวอย่าง:
สร้างไฟล์ pages/blog/[slug].js

import { useRouter } from 'next/router';

export default function BlogPostPage() {
  const router = useRouter();
  const { slug } = router.query;

  return <h1>กำลังอ่านบทความ: {slug}</h1>;
}

เมื่อมีคนเข้าไปที่ /blog/my-first-post หรือ /blog/hello-world ค่า {slug} จะเปลี่ยนไปตาม URL อัตโนมัติ

 

API Routes: ใช้ pages/api/ เพื่อสร้าง API ง่าย ๆ

Next.js ไม่ได้ใช้ pages/ แค่สำหรับสร้างหน้าเว็บเท่านั้น มันยังสามารถใช้สำหรับสร้าง API ได้อีกด้วย!

ถ้าคุณสร้างไฟล์ pages/api/hello.js และเขียนโค้ดแบบนี้:

export default function handler(req, res) {
  res.status(200).json({ message: "Hello from API!" });
}

ตอนนี้คุณสามารถเรียก API นี้ได้ที่ /api/hello โดยไม่ต้องตั้งค่าเพิ่ม 


Middleware และการ Redirect Routing

ถ้าคุณอยากควบคุม Routing แบบละเอียดขึ้น Next.js ก็มีเครื่องมือให้ เช่น Middleware และ Redirects

Middleware ช่วยให้คุณสามารถจัดการกับ Request ก่อนที่มันจะไปถึงหน้าเว็บ เช่น ตรวจสอบสิทธิ์การเข้าถึง

ตัวอย่าง Middleware

สร้างไฟล์ middleware.js

import { NextResponse } from "next/server";

export function middleware(req) {
  const url = req.nextUrl.clone();
  if (!req.cookies.auth) {
    url.pathname = "/login";
    return NextResponse.redirect(url);
  }
  return NextResponse.next();
}

จากนั้นกำหนดให้ Middleware ทำงานใน next.config.js

module.exports = {
  async redirects() {
    return [
      {
        source: "/old-page",
        destination: "/new-page",
        permanent: true,
      },
    ];
  },
};
 

ข้อดีของระบบ Routing อัตโนมัติใน Next.js

  • ลดโค้ดที่ต้องเขียน – ไม่ต้องมานั่งเซ็ตเส้นทางเอง
  • SEO-Friendly – เส้นทางแบบ Static และ Dynamic ทำงานได้ดี
  • มี API Routes ในตัว – ไม่ต้องแยก Backend ออกมาเอง
  • รองรับ Dynamic Routing – เหมาะกับเว็บที่มีเนื้อหาหลายหน้า
  • สรุป: Next.js ทำให้ Routing ง่ายขึ้นเยอะ!


ระบบ Routing ใน Next.js ออกแบบมาให้ใช้ง่ายสุด ๆ แค่สร้างไฟล์ในโฟลเดอร์ pages/ ก็สามารถเข้าถึง URL นั้นได้เลย ไม่ต้องตั้งค่าอะไรเพิ่มเติม

ถ้าคุณต้องการ Routing ที่ซับซ้อนขึ้น เช่น Dynamic Routes หรือ API Routes Next.js ก็รองรับทั้งหมดโดยไม่ต้องพึ่ง Third-party library เลย 

พร้อมจะใช้ Next.js ในโปรเจกต์ของคุณหรือยัง? ถ้าพร้อมแล้ว ลองเล่นกับ pages/ ดูเลย แล้วคุณจะติดใจ! 

วันจันทร์ที่ 17 กุมภาพันธ์ พ.ศ. 2568

โครงสร้างไฟล์พื้นฐานของ Next.js

ถ้าพูดถึง Next.js หลายคนอาจจะคิดว่ามันเป็น React Framework ที่ใช้ทำ SSR (Server-side Rendering) หรือ SSG (Static Site Generation) ซึ่งก็ถูกแล้ว! แต่ก่อนจะเริ่มใช้งาน Next.js เราต้องมาทำความเข้าใจกับโครงสร้างไฟล์ของมันก่อน เพราะถ้ารู้ว่ามีไฟล์อะไร อยู่ตรงไหน ใช้ทำอะไร ชีวิตจะง่ายขึ้นเยอะ

โครงสร้างไฟล์หลักใน Next.js  

เมื่อเราสร้างโปรเจกต์ Next.js ใหม่ ๆ ด้วยคำสั่ง  

npx create-next-app@latest my-app

หรือ

yarn create next-app my-app
 

เราจะได้โฟลเดอร์ที่มีโครงสร้างพื้นฐานหน้าตาประมาณนี้ 

my-app/
│-- .next/
│-- node_modules/
│-- public/
│-- src/ (บางโปรเจกต์อาจไม่มี)
│-- pages/
│-- components/
│-- styles/
│-- package.json
│-- next.config.js
│-- .gitignore
│-- README.md


1. โฟลเดอร์ .next/

อันนี้เป็นโฟลเดอร์ที่ Next.js ใช้เก็บไฟล์ที่คอมไพล์แล้ว ไม่ต้องไปยุ่งกับมัน เราแค่รู้ว่ามันเป็นไฟล์ที่ Next.js ใช้ตอนรันโปรเจกต์พอ

 

2. โฟลเดอร์ node_modules/

อันนี้คือที่อยู่ของ dependency ต่าง ๆ ที่ถูกติดตั้งผ่าน npm หรือ yarn อย่าไปแก้ไขอะไรในนี้ เพราะมันสร้างขึ้นโดยอัตโนมัติ 


3. โฟลเดอร์ public/

โฟลเดอร์นี้เอาไว้เก็บไฟล์ static เช่น รูปภาพ ไอคอน หรือไฟล์อื่น ๆ ที่ต้องการเข้าถึงโดยตรงผ่าน URL เช่น ถ้ามีไฟล์ logo.png อยู่ใน public/ เราจะเข้าถึงมันได้ที่

http://localhost:3000/logo.png 

ไม่ต้อง import รูปจาก public ในโค้ด แค่ใช้ path ตรง ๆ ได้เลย

 

4. โฟลเดอร์ pages/

นี่คือหัวใจของ Next.js ทุกไฟล์ในโฟลเดอร์นี้จะกลายเป็นหน้าเว็บอัตโนมัติ เช่น 

pages/
│-- index.js  (แสดงที่ /)
│-- about.js  (แสดงที่ /about)
│-- contact.js (แสดงที่ /contact)
│-- blog/
│   ├── index.js   (แสดงที่ /blog)
│   ├── [id].js    (Dynamic Route เช่น /blog/1, /blog/2)
│   ├── new.js     (แสดงที่ /blog/new)

  • Static Route → about.js จะกลายเป็น /about
  • Dynamic Route → [id].js จะกลายเป็น /blog/:id
  • Nested Route → ใช้โฟลเดอร์ย่อย เช่น /blog/new มาจาก pages/blog/new.js

ถ้าใน pages/ มี \_app.js และ \_document.js

  • _app.js → ใช้กำหนด Layout หลักของเว็บ
  • _document.js → ใช้แก้ไขโครงสร้าง HTML พื้นฐานของ Next.js

 

5. โฟลเดอร์ components/

Next.js ไม่มีบังคับให้ต้องมีโฟลเดอร์นี้ แต่ส่วนใหญ่เราจะสร้างขึ้นมาเพื่อแยก UI ออกเป็น Component เช่น

  • Navbar.js
  • Footer.js
  • Button.js

จากนั้นก็ import ไปใช้ใน pages/ ได้เลย 

 

6. โฟลเดอร์ styles/

เป็นที่เก็บไฟล์ CSS หรือ SCSS เช่น

  • globals.css → ใช้กำหนดสไตล์ทั่วทั้งเว็บ
  • Home.module.css → เป็น CSS Module ใช้เฉพาะ Component นั้น ๆ

Next.js รองรับ CSS หลายรูปแบบ เช่น

  • CSS ปกติ
  • SCSS/SASS
  • Tailwind CSS (ต้องติดตั้งเพิ่ม)
  • CSS-in-JS (เช่น styled-components)

 

7. ไฟล์ package.json

ไฟล์นี้สำคัญมาก! มันบอกว่าโปรเจกต์นี้ใช้ package อะไรบ้าง รวมถึงสคริปต์ที่ใช้รันคำสั่ง เช่น 

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

  • next dev → รันโหมดพัฒนา
  • next build → สร้างไฟล์สำหรับ production
  • next start → รันเซิร์ฟเวอร์ production

 

8. ไฟล์ next.config.js

ไฟล์นี้ใช้ตั้งค่าต่าง ๆ ของ Next.js เช่น

  • ปรับแต่ง Webpack
  • ตั้งค่า Redirect
  • กำหนด Environment Variables

ตัวอย่าง 

module.exports = {
  images: {
    domains: ['example.com'],
  },
  reactStrictMode: true,
}


9. ไฟล์ .gitignore

ใช้กำหนดว่าไฟล์ไหนบ้างที่ไม่ต้องการให้ Git ติดตาม เช่น

node_modules/
.next/
.env 

 

10. ไฟล์ README.md

ไฟล์นี้ใช้สำหรับให้ข้อมูลเกี่ยวกับโปรเจกต์ เช่น วิธีติดตั้ง วิธีใช้งาน ฯลฯ 


Next.js เป็น Framework ที่จัดโครงสร้างไฟล์ให้เป็นระบบระเบียบ ถ้าเราเข้าใจว่าแต่ละโฟลเดอร์และไฟล์ทำหน้าที่อะไร เราจะพัฒนาเว็บได้เร็วขึ้น และเขียนโค้ดได้สะอาดขึ้น

วันอาทิตย์ที่ 16 กุมภาพันธ์ พ.ศ. 2568

ติดตั้ง Next.js และเริ่มโปรเจกต์แรกแบบง่าย ๆ

    Next.js คือเฟรมเวิร์กที่พัฒนาขึ้นจาก React.js ซึ่งได้รับความนิยมอย่างมากในช่วงหลัง เพราะมันช่วยให้การพัฒนาเว็บแอปพลิเคชันที่ต้องการฟีเจอร์ขั้นสูง เช่น การเรนเดอร์ฝั่งเซิร์ฟเวอร์ (SSR), Static Site Generation (SSG), และการจัดการ SEO ทำได้ง่ายขึ้น แต่หากคุณเพิ่งเริ่มต้นกับ Next.js อาจจะรู้สึกงง ๆ ว่าต้องทำอะไรบ้างเพื่อเริ่มต้นโปรเจกต์แรกของคุณ

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

ขั้นตอนที่ 1: ติดตั้ง Node.js และ npm

    ก่อนที่เราจะเริ่มโปรเจกต์ใน Next.js ได้ เราต้องติดตั้ง Node.js และ npm (Node Package Manager) ให้เรียบร้อยก่อน ถ้าคุณยังไม่ได้ติดตั้ง Node.js หรือไม่แน่ใจว่ามีแล้วหรือยัง สามารถตรวจสอบได้โดยการเปิด Terminal หรือ Command Prompt แล้วพิมพ์คำสั่งเหล่านี้:

node -v

และ

npm -v

หากมีการแสดงเวอร์ชันออกมาแสดงว่าคุณได้ติดตั้ง Node.js และ npm แล้ว แต่หากยังไม่มีก็สามารถดาวน์โหลด Node.js ได้ที่ https://nodejs.org เลือกเวอร์ชันที่แนะนำ (LTS) และติดตั้งตามขั้นตอน

เมื่อเสร็จแล้วลองตรวจสอบอีกครั้งว่ามีการติดตั้งสำเร็จแล้วหรือยัง

ขั้นตอนที่ 2: สร้างโปรเจกต์ใหม่ด้วย Next.js

เมื่อคุณติดตั้ง Node.js และ npm เรียบร้อยแล้ว ขั้นตอนต่อไปคือการสร้างโปรเจกต์ใหม่ด้วย Next.js ซึ่งเราสามารถใช้คำสั่ง create-next-app ในการสร้างโปรเจกต์ได้อย่างง่ายดาย

  1.     เปิด Terminal หรือ Command Prompt
  2.     ใช้คำสั่งนี้เพื่อสร้างโปรเจกต์ใหม่

npx create-next-app@latest ชื่อโปรเจกต์ของคุณ

ตัวอย่างเช่น หากคุณอยากตั้งชื่อโปรเจกต์ว่า my-first-next-project ก็พิมพ์คำสั่งนี้:

npx create-next-app@latest my-first-next-project

คำสั่งนี้จะดาวน์โหลดเทมเพลตพื้นฐานของ Next.js และติดตั้ง dependencies ที่จำเป็นทั้งหมดให้คุณ โดยไม่ต้องตั้งค่ามือเอง

ขั้นตอนที่ 3: เข้าไปในโฟลเดอร์โปรเจกต์

เมื่อการสร้างโปรเจกต์เสร็จสมบูรณ์ ให้เข้าไปในโฟลเดอร์ของโปรเจกต์ที่เพิ่งสร้างขึ้น โดยใช้คำสั่ง:

cd my-first-next-project

ขั้นตอนที่ 4: รันโปรเจกต์แรก

หลังจากที่คุณเข้าไปในโฟลเดอร์โปรเจกต์แล้ว คุณสามารถเริ่มรันโปรเจกต์ของคุณได้ทันที โดยใช้คำสั่งนี้:

npm run dev

คำสั่งนี้จะเริ่มเซิร์ฟเวอร์ในโหมดพัฒนา (development mode) และโปรเจกต์ของคุณจะรันที่ http://localhost:3000 ถ้าทุกอย่างทำงานถูกต้อง คุณสามารถเปิดเบราว์เซอร์แล้วพิมพ์ URL นี้เพื่อดูหน้าเว็บแรกของคุณ

ขั้นตอนที่ 5: ทำความเข้าใจโครงสร้างโปรเจกต์

เมื่อคุณสร้างโปรเจกต์ Next.js ใหม่แล้ว คุณจะเห็นโครงสร้างของโฟลเดอร์ที่ค่อนข้างง่ายและเข้าใจได้ไม่ยาก ลองมาดูกันว่าในโปรเจกต์ที่สร้างขึ้นมาจะมีโฟลเดอร์และไฟล์อะไรบ้าง:

  • pages/: โฟลเดอร์นี้จะเก็บไฟล์ที่เป็นหน้าเว็บ (pages) ของโปรเจกต์ เช่น index.js คือหน้าแรกของเว็บไซต์
  • public/: โฟลเดอร์นี้จะเก็บไฟล์ที่เป็นสาธารณะ เช่น รูปภาพ ไฟล์ .txt หรือไฟล์อื่น ๆ ที่สามารถเข้าถึงได้จาก URL
  • styles/: โฟลเดอร์นี้จะเก็บไฟล์ CSS สำหรับตกแต่งหน้าเว็บ
  • node_modules/: โฟลเดอร์ที่ npm สร้างขึ้นเพื่อเก็บ dependencies ที่จำเป็นสำหรับโปรเจกต์
  • package.json: ไฟล์นี้จะเก็บข้อมูลเกี่ยวกับโปรเจกต์ เช่น dependencies, scripts, และ metadata อื่น ๆ

ในโฟลเดอร์ pages คุณจะเห็นไฟล์ index.js ซึ่งเป็นหน้าแรกของเว็บไซต์ คุณสามารถแก้ไขไฟล์นี้เพื่อเปลี่ยนแปลงเนื้อหาของหน้าแรกได้ทันที

ขั้นตอนที่ 6: แก้ไขหน้าแรกของคุณ

ลองเปิดไฟล์ pages/index.js และเปลี่ยนเนื้อหาภายในไฟล์นี้สักหน่อยเพื่อทดสอบการทำงานของ Next.js ตัวอย่างเช่น:

function HomePage() {
  return (
    <div>
      <h1>ยินดีต้อนรับสู่โปรเจกต์แรกของคุณใน Next.js!</h1>
      <p>นี่คือหน้าแรกของเว็บไซต์ที่คุณสร้างขึ้นมา</p>
    </div>
  );
}

export default HomePage;

จากนั้นบันทึกไฟล์และไปที่เบราว์เซอร์เพื่อรีเฟรชหน้า http://localhost:3000 คุณจะเห็นการเปลี่ยนแปลงที่คุณทำทันที

ขั้นตอนที่ 7: การเพิ่มหน้าใหม่

หนึ่งในคุณสมบัติที่ยอดเยี่ยมของ Next.js คือระบบ Routing ที่อัตโนมัติ เพียงแค่คุณสร้างไฟล์ใหม่ในโฟลเดอร์ pages หน้าใหม่ก็จะถูกสร้างขึ้นโดยอัตโนมัติ ลองสร้างไฟล์ใหม่ชื่อ about.js ในโฟลเดอร์ pages และใส่โค้ดนี้:

function AboutPage() {
  return (
    <div>
      <h1>เกี่ยวกับเรา</h1>
      <p>นี่คือหน้าที่เกี่ยวกับเว็บไซต์ของเรา</p>
    </div>
  );
}

export default AboutPage;

ตอนนี้คุณสามารถไปที่ http://localhost:3000/about เพื่อดูหน้า "เกี่ยวกับเรา" ที่คุณเพิ่งสร้างขึ้นได้เลย

ขั้นตอนที่ 8: การใช้งาน Link ใน Next.js

Next.js มีคอมโพเนนต์ที่เรียกว่า Link ซึ่งช่วยให้การทำ routing ภายในเว็บไซต์ง่ายขึ้นโดยไม่ต้องโหลดหน้าใหม่ทั้งหมด ลองใช้ Link เพื่อเพิ่มลิงก์ไปยังหน้า "เกี่ยวกับเรา" ที่คุณสร้างขึ้น:

เปิดไฟล์ index.js แล้วเพิ่มโค้ดนี้:

import Link from 'next/link';

function HomePage() {
  return (
    <div>
      <h1>ยินดีต้อนรับสู่โปรเจกต์แรกของคุณใน Next.js!</h1>
      <p><Link href="/about">ไปยังหน้าที่เกี่ยวกับเรา</Link></p>
    </div>
  );
}

export default HomePage;

ตอนนี้เมื่อคุณไปที่หน้าแรก คุณจะเห็นลิงก์ที่สามารถคลิกเพื่อไปยังหน้า "เกี่ยวกับเรา" ได้ทันที

สรุป

การเริ่มต้นกับ Next.js นั้นไม่ยากเลย! เราเพียงแค่ต้องติดตั้ง Node.js, สร้างโปรเจกต์ใหม่ด้วยคำสั่ง create-next-app, รันโปรเจกต์, แล้วเริ่มแก้ไขหน้าเว็บและเพิ่มหน้าใหม่ตามต้องการ Next.js ทำให้การพัฒนาเว็บแอปพลิเคชันง่ายขึ้นและมีเครื่องมือที่ครบครันสำหรับการทำงานในระดับสูง

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

วันเสาร์ที่ 15 กุมภาพันธ์ พ.ศ. 2568

ข้อแตกต่างระหว่าง Next.js กับ React.js

    ในวงการพัฒนาเว็บวันนี้ คงไม่มีใครไม่รู้จัก React.js หรือ Next.js ที่ได้รับความนิยมอย่างมากจากนักพัฒนาเว็บทั่วโลก แต่หลายคนอาจจะยังไม่รู้ว่า React.js กับ Next.js นั้นมีข้อแตกต่างกันอย่างไร และควรเลือกใช้อะไรดี วันนี้เราจะมาพูดถึงข้อแตกต่างระหว่างสองตัวนี้แบบง่าย ๆ ครับ

React.js คืออะไร?

    ก่อนที่เราจะไปพูดถึงความแตกต่าง เรามาทำความเข้าใจกันก่อนว่า React.js คืออะไร React.js เป็น JavaScript library ที่ถูกพัฒนาโดย Facebook (หรือ Meta ในปัจจุบัน) เพื่อช่วยให้การพัฒนา UI (User Interface) ของแอปพลิเคชันเว็บง่ายขึ้น โดยมันใช้แนวคิดที่เรียกว่า "component-based architecture" หรือการออกแบบเป็นส่วน ๆ ทำให้เราสามารถสร้างส่วนต่าง ๆ ของ UI แล้วนำมาประกอบกันเป็นแอปพลิเคชันใหญ่ได้

    React.js ให้เราได้ทำงานกับ "component" ที่มีสถานะ (state) และคุณสมบัติ (props) ซึ่งทำให้การจัดการกับ UI และการแสดงผลข้อมูลจากแหล่งต่าง ๆ ทำได้ง่ายและสะดวก

Next.js คืออะไร?

    Next.js คือเว็บเฟรมเวิร์กที่ถูกสร้างขึ้นมาโดย Vercel ที่ใช้ React.js เป็นฐานหลัก แต่มันมีคุณสมบัติที่ทำให้การพัฒนาเว็บแอปพลิเคชันง่ายขึ้น และยืดหยุ่นมากขึ้น ไม่ว่าจะเป็นการจัดการกับ SEO (Search Engine Optimization) การเรนเดอร์ข้อมูลที่ฝั่งเซิร์ฟเวอร์ (Server-side Rendering หรือ SSR) หรือการทำ Static Site Generation (SSG) นอกจากนี้ Next.js ยังรองรับการพัฒนาแบบ full-stack ได้อีกด้วย

    Next.js เป็นเฟรมเวิร์กที่รวมหลาย ๆ ฟีเจอร์ที่จำเป็นในการสร้างเว็บแอปพลิเคชันในโลกยุคใหม่ ซึ่ง React.js เองไม่ได้มีฟีเจอร์เหล่านี้มาให้ในตัว

ความแตกต่างหลักระหว่าง React.js กับ Next.js

1. React.js เป็นไลบรารี ส่วน Next.js เป็นเฟรมเวิร์ก

    สิ่งแรกที่ต้องรู้คือ React.js เป็นไลบรารี (Library) ที่ช่วยในการสร้าง UI ในขณะที่ Next.js เป็นเฟรมเวิร์ก (Framework) ที่ให้โครงสร้างการพัฒนาแอปพลิเคชัน โดย Next.js ได้รวมฟีเจอร์มากมายที่ช่วยในการพัฒนาเว็บแอปพลิเคชันให้สะดวกและง่ายขึ้น ไม่ว่าจะเป็นการทำ SEO, การเรนเดอร์ฝั่งเซิร์ฟเวอร์, หรือการทำ Static Generation

2. Server-Side Rendering (SSR) และ Static Site Generation (SSG)

    หนึ่งในข้อดีที่ใหญ่ที่สุดของ Next.js คือการรองรับการเรนเดอร์ฝั่งเซิร์ฟเวอร์ (SSR) และการสร้างเว็บไซต์แบบ Static (SSG) ซึ่งช่วยให้เว็บไซต์โหลดเร็วและรองรับ SEO ได้ดีขึ้น

  •     SSR คือการที่เรานำข้อมูลมาจากเซิร์ฟเวอร์แล้วเรนเดอร์หน้าบนเซิร์ฟเวอร์ก่อนที่จะส่งไปให้ผู้ใช้ เมื่อเทียบกับ React.js ที่จะเรนเดอร์ส่วนใหญ่บนฝั่งไคลเอนต์ (Client-side rendering หรือ CSR)
  •     SSG คือการสร้างไฟล์ HTML ที่ได้จากข้อมูลที่เรากำหนดล่วงหน้าไว้แล้ว เช่น ข้อมูลของบทความในบล็อก ซึ่งจะถูกสร้างขึ้นตอนที่เรา build เว็บไซต์

    React.js เองไม่ได้มีฟีเจอร์พวกนี้มาให้ ต้องมีการตั้งค่าเพิ่มเติมเพื่อให้ทำงานในลักษณะนี้

3. Routing ใน Next.js

    ใน React.js การทำ routing หรือการสร้างเส้นทางไปยังหน้าอื่น ๆ ของเว็บไซต์จะต้องใช้ไลบรารีเสริม เช่น React Router เพื่อให้สามารถเปลี่ยนหน้าได้ แต่ใน Next.js นั้นมีระบบ routing มาให้พร้อมเลยโดยไม่ต้องติดตั้งอะไรเพิ่ม โดยการสร้างไฟล์ในโฟลเดอร์ pages ในโปรเจกต์จะทำให้ไฟล์นั้นกลายเป็นหน้าเว็บได้ทันที

    การทำ routing ใน React.js ต้องมีกระบวนการติดตั้งและตั้งค่ามากกว่า ขณะที่ Next.js สะดวกกว่าเยอะ

4. การทำงานกับ Data Fetching

    Next.js รองรับการดึงข้อมูลทั้งในฝั่งเซิร์ฟเวอร์และฝั่งไคลเอนต์ ซึ่งมีฟีเจอร์ที่ช่วยให้การดึงข้อมูลเป็นไปได้อย่างมีประสิทธิภาพ ตัวอย่างเช่น getStaticProps, getServerSideProps และ getInitialProps ที่จะช่วยให้สามารถดึงข้อมูลได้ตามประเภทการเรนเดอร์ที่ต้องการ

    ใน React.js การดึงข้อมูลจะทำได้ผ่านการใช้ useEffect หรือ componentDidMount และมักจะต้องมีการจัดการเองอย่างละเอียดกว่า

5. การจัดการ SEO

    ถ้าพูดถึง SEO บนเว็บแอปพลิเคชัน Next.js ทำได้ดีกว่า React.js เพราะการเรนเดอร์ฝั่งเซิร์ฟเวอร์ (SSR) ทำให้สามารถส่ง HTML ที่เต็มรูปแบบไปยังบอทของ Google ซึ่งช่วยให้เว็บไซต์ติดอันดับการค้นหาได้ดีกว่า ในขณะที่ React.js นั้นมักจะต้องมีการทำ SEO ด้วยมือหรือใช้เครื่องมือเสริม เช่น React Helmet

สรุป

    ในที่สุดแล้ว การเลือกใช้ React.js หรือ Next.js ขึ้นอยู่กับความต้องการและลักษณะของโปรเจกต์ หากคุณต้องการพัฒนาแค่ UI หรือ Single Page Application ที่ไม่ได้มีฟีเจอร์พิเศษมากมาย React.js ก็เพียงพอแล้ว แต่ถ้าคุณต้องการฟีเจอร์ที่มากกว่า เช่น การรองรับ SSR, SSG, SEO ที่ดีขึ้น และการทำ routing ที่สะดวก Next.js ก็เป็นตัวเลือกที่ดีที่สุด

    โดยสรุปแล้ว React.js เป็นไลบรารีที่ให้คุณสร้าง UI ได้ง่าย ๆ ส่วน Next.js เป็นเฟรมเวิร์กที่ให้โครงสร้างการพัฒนาเว็บที่ครบครันกว่า ทั้งการเรนเดอร์ข้อมูลบนเซิร์ฟเวอร์, การจัดการ routing, และการทำ SEO ที่เหนือกว่า

    หวังว่าบล็อกนี้จะช่วยให้คุณเห็นข้อแตกต่างระหว่าง Next.js และ React.js และสามารถตัดสินใจเลือกใช้งานตามความต้องการของคุณได้ดีขึ้นนะครับ!

Next.js คืออะไร และทำไมต้องใช้ Next.js

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

Next.js คืออะไร?

    Next.js เป็นเฟรมเวิร์กที่ถูกสร้างขึ้นมาบน React ซึ่งช่วยให้การพัฒนาเว็บแอปเป็นเรื่องง่ายขึ้น โดยเฉพาะในเรื่องของการทำงานฝั่งเซิร์ฟเวอร์ (Server-side Rendering) และการทำ SEO ซึ่งเป็นจุดที่ React ปกติทำได้ยาก

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

ทำไมต้องใช้ Next.js?

    1. โหลดเร็วกว่า ด้วย Server-side Rendering (SSR) และ Static Site Generation (SSG) ปกติแล้ว React ใช้วิธี Client-side Rendering (CSR) คือโหลดหน้าเว็บมาก่อน แล้วไปดึงข้อมูลจาก API มาเติมทีหลัง ทำให้บางครั้งหน้าเว็บโหลดมาแล้ว แต่ยังไม่มีข้อมูล ต้องรออีกแป๊บนึงถึงจะแสดงผลครบ ซึ่งไม่ดีต่อ SEO และ UX เลย

แต่ Next.js แก้ปัญหานี้ด้วย SSR และ SSG

  • SSR (Server-side Rendering): ดึงข้อมูลจากเซิร์ฟเวอร์ก่อน แล้วส่งหน้าเว็บที่มีข้อมูลพร้อมให้ผู้ใช้ทันที โหลดเร็วขึ้นเยอะ!
  • SSG (Static Site Generation): สร้างหน้าเว็บเป็นไฟล์ HTML ตั้งแต่ตอน Build แล้วโหลดแบบ Static ทำให้เว็บเร็วสุด ๆ แถมยังลดภาระเซิร์ฟเวอร์อีกด้วย

    2. SEO ดีขึ้น เพราะ Google อ่านเนื้อหาได้เลย หนึ่งในปัญหาใหญ่ของ React คือ Google Bot ไม่สามารถอ่านเนื้อหาบนเว็บที่ใช้ CSR ได้ดีนัก เพราะทุกอย่างโหลดผ่าน JavaScript แต่ถ้าใช้ Next.js ที่รองรับ SSR และ SSG ก็จะช่วยให้ Google มองเห็นเนื้อหาได้ง่ายขึ้น ส่งผลให้ SEO ของเราดีขึ้นแบบเห็นได้ชัด

    3. มีระบบ Routing อัตโนมัติ (File-based Routing) ปกติถ้าใช้ React อย่างเดียว เราต้องใช้ React Router มาจัดการเส้นทาง (Routes) เอง แต่ใน Next.js แค่สร้างไฟล์ในโฟลเดอร์ pages/ เช่น:

  • pages/index.js → /
  • pages/about.js → /about
  • pages/products/index.js → /products


แค่สร้างไฟล์ก็ได้ Routing อัตโนมัติ ไม่ต้อง config เองให้ยุ่งยาก

    4. API Routes - ทำ Backend ได้ในตัว Next.js ไม่ได้มีดีแค่ Frontend แต่ยังให้เราสร้าง API ได้เลยในโฟลเดอร์ pages/api/ เช่น:

  • pages/api/hello.js → GET /api/hello

    ซึ่งเราสามารถใช้ API นี้เชื่อมต่อกับฐานข้อมูล หรือใช้ร่วมกับ Frontend ได้ทันที ไม่ต้องไปเปิดเซิร์ฟเวอร์แยก

    5. รองรับ Image Optimization อัตโนมัติ Next.js มีฟีเจอร์ next/image ที่ช่วยให้เราจัดการภาพได้ง่ายขึ้น ไม่ต้องมานั่ง Optimize เอง เช่น การปรับขนาดอัตโนมัติ การแปลงเป็น WebP และการโหลดแบบ Lazy Loading เพื่อช่วยให้เว็บโหลดเร็วขึ้น

    6. รองรับการ Deploy ง่าย ๆ บน Vercel Next.js ถูกสร้างโดยทีมงานของ Vercel ซึ่งเป็นแพลตฟอร์มสำหรับ Deploy เว็บแบบ Serverless เราสามารถเชื่อม GitHub หรือ GitLab แล้วกด Deploy ได้ในไม่กี่คลิก แถมมีฟีเจอร์ CI/CD ให้ใช้งานด้วย

    7. รองรับการใช้งานกับ Tailwind CSS ได้อย่างง่ายดาย ถ้าใครชอบใช้ Tailwind CSS ก็สามารถติดตั้งกับ Next.js ได้ง่าย ๆ และใช้งานร่วมกันได้อย่างสมบูรณ์แบบ ทำให้การเขียน UI เร็วขึ้นมาก

Next.js เหมาะกับใคร?

    Next.js เหมาะกับนักพัฒนาเว็บที่ต้องการ พัฒนาเว็บให้เร็วขึ้น ทำ SEO ให้ดีขึ้น และลดความซับซ้อนของโปรเจกต์ ไม่ว่าจะเป็น

  • เว็บทั่วไปที่ต้องการ SEO เช่น บล็อก หรือเว็บข่าว
  • เว็บอีคอมเมิร์ซ ที่ต้องโหลดข้อมูลเร็วและรองรับ SEO
  • Dashboard หรือแอปพลิเคชันที่ใช้ข้อมูลเยอะ ๆ
  • SaaS หรือเว็บ Subscription ที่ต้องการประสิทธิภาพสูง
  • เว็บที่ต้องการ Full-stack API ในตัว ไม่ต้องเปิดเซิร์ฟเวอร์แยก


ข้อเสียของ Next.js ที่ควรรู้

    แน่นอนว่าไม่มีอะไรสมบูรณ์แบบ Next.js ก็มีข้อจำกัดบางอย่าง เช่น

  • เรียนรู้เพิ่มขึ้นจาก React ปกติ เพราะมี SSR, SSG, ISR ที่ต้องเข้าใจเพิ่ม
  • SSR อาจจะช้ากว่า CSR ถ้าต้องดึงข้อมูลเยอะมาก เพราะเซิร์ฟเวอร์ต้อง Generate หน้าใหม่ทุกครั้ง
  • Hosting อาจต้องใช้แพลตฟอร์มเฉพาะ เช่น Vercel หรือโฮสต์ที่รองรับ SSR ไม่ใช่ทุกที่รองรับได้ง่ายเหมือน React ปกติ


สรุป: Next.js ดีไหม? ควรใช้หรือเปล่า?

    ถ้าคุณใช้ React และต้องการเพิ่มประสิทธิภาพให้เว็บ โหลดเร็วขึ้น ทำ SEO ได้ดีขึ้น และมีฟีเจอร์ Backend ในตัว Next.js คือคำตอบ! โดยเฉพาะถ้าคุณพัฒนาเว็บที่เน้นความเร็วและต้องการให้ Google มองเห็นเนื้อหาแบบเต็ม ๆ

    แต่ถ้าโปรเจกต์ของคุณเป็น Single Page Application (SPA) ธรรมดาที่ไม่สน SEO หรือโหลดข้อมูลฝั่งไคลเอนต์เป็นหลัก การใช้ React ปกติอาจจะเหมาะกว่า

แต่ถ้าอยากลอง Next.js ก็ไม่ยาก! สามารถติดตั้งและเริ่มต้นใช้งานได้ง่าย ๆ แค่รันคำสั่งนี้:

npx create-next-app@latest my-next-app
cd my-next-app
npm run dev

แล้วเข้าไปที่ http://localhost:3000 แค่นี้ก็พร้อมใช้งาน Next.js แล้ว!

    นี่คือภาพรวมของ Next.js และเหตุผลว่าทำไมมันถึงเป็นเฟรมเวิร์กที่นักพัฒนาหลายคนชื่นชอบ ถ้าคุณกำลังมองหาเครื่องมือที่จะช่วยให้เว็บของคุณเร็วขึ้นและรองรับ SEO ได้ดีขึ้น Next.js คือตัวเลือกที่ไม่ควรพลาด!

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

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