Bắt đầu với Next.js 15: Hướng dẫn Toàn diện

10 phút đọcCong Dinh
Bắt đầu với Next.js 15: Hướng dẫn Toàn diện

Bắt đầu với Next.js 15: Hướng dẫn Toàn diện

Next.js đã trở thành framework React hàng đầu cho việc xây dựng ứng dụng web hiện đại, và phiên bản 15 mang đến những cải tiến đáng kể về hiệu suất và trải nghiệm phát triển. Trong bài viết này, chúng ta sẽ khám phá những tính năng nổi bật của Next.js 15 và cách bắt đầu xây dựng ứng dụng của bạn.

Giới thiệu

Next.js là gì?

Next.js là một framework React mã nguồn mở được phát triển bởi Vercel, cung cấp các tính năng như server-side rendering (SSR), static site generation (SSG), và routing tích hợp sẵn. Framework này giúp developers xây dựng ứng dụng web có hiệu suất cao với trải nghiệm phát triển tuyệt vời.

Tại sao chọn Next.js 15?

Next.js 15 không chỉ là một bản cập nhật thông thường - đây là một bước tiến lớn với nhiều cải tiến quan trọng:

  • Performance tốt hơn: Thời gian build nhanh hơn đáng kể với Turbopack
  • Developer Experience cải thiện: Công cụ và error messages tốt hơn
  • React 19 Support: Hỗ trợ đầy đủ các tính năng mới nhất của React
  • Stability: Production-ready với nhiều bug fixes và optimizations

Ai nên đọc bài này?

Bài viết này phù hợp với:

  • Developers đã có kiến thức cơ bản về React
  • Những người muốn học về Next.js từ đầu
  • Developers muốn nâng cấp từ phiên bản Next.js cũ lên v15

Tính năng nổi bật của Next.js 15

1. App Router - Cách tiếp cận mới cho Routing

App Router là một kiến trúc routing hoàn toàn mới được giới thiệu từ Next.js 13 và được hoàn thiện trong v15. Khác với Pages Router cũ, App Router sử dụng cấu trúc thư mục để định nghĩa routes và hỗ trợ React Server Components mặc định.

Ưu điểm của App Router:

  • Folder-based Routing: Mỗi thư mục trong app directory đại diện cho một route segment
  • Layouts: Chia sẻ UI giữa nhiều pages mà không cần re-render
  • Loading States: Built-in support cho loading và error states
  • Nested Routing: Dễ dàng tạo nested routes với layouts lồng nhau
// app/layout.tsx - Root Layout
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="vi">
      <body>
        <header>
          <nav>Navigation Bar</nav>
        </header>
        <main>{children}</main>
        <footer>Footer Content</footer>
      </body>
    </html>
  );
}

2. React Server Components - Tối ưu Performance

React Server Components (RSC) là một tính năng mạnh mẽ cho phép render components trên server, giúp giảm JavaScript bundle size gửi đến client và cải thiện hiệu suất tải trang.

Lợi ích của Server Components:

  • Reduced Bundle Size: Code của server components không được gửi đến client
  • Direct Data Access: Truy cập database và API trực tiếp mà không cần API routes
  • Better Performance: Faster initial page load và improved SEO
  • Security: Giữ sensitive code (API keys, database queries) trên server
// app/blog/page.tsx - Server Component
async function BlogPage() {
  // Fetch data trực tiếp trong component
  const posts = await db.query('SELECT * FROM posts ORDER BY date DESC');
  
  return (
    <div>
      <h1>Blog Posts</h1>
      <div className="grid gap-6">
        {posts.map((post) => (
          <BlogCard key={post.id} post={post} />
        ))}
      </div>
    </div>
  );
}
 
export default BlogPage;

3. Server Actions - Xử lý Form đơn giản

Server Actions là một tính năng mới cho phép bạn gọi các hàm server trực tiếp từ client mà không cần tạo API endpoints riêng biệt. Điều này làm đơn giản hóa đáng kể việc xử lý forms và mutations.

// app/actions.ts
'use server';
 
export async function createPost(formData: FormData) {
  const title = formData.get('title') as string;
  const content = formData.get('content') as string;
  
  // Validate data
  if (!title || !content) {
    return { error: 'Title and content are required' };
  }
  
  // Save to database
  await db.posts.create({
    data: { title, content, createdAt: new Date() }
  });
  
  return { success: true };
}
// app/new-post/page.tsx
import { createPost } from '../actions';
 
export default function NewPostPage() {
  return (
    <form action={createPost}>
      <input type="text" name="title" placeholder="Post Title" required />
      <textarea name="content" placeholder="Post Content" required />
      <button type="submit">Create Post</button>
    </form>
  );
}

4. Turbopack - Build nhanh hơn

Turbopack là bundler mới được viết bằng Rust, thay thế Webpack trong Next.js 15. Nó mang lại tốc độ build nhanh hơn đáng kể, đặc biệt với các dự án lớn.

Cải tiến về tốc độ:

  • Fast Refresh nhanh hơn 700x so với Webpack
  • Cold starts nhanh hơn 10x
  • Incremental builds được tối ưu hóa

Hướng dẫn Thực hành

Cài đặt Next.js 15

Để bắt đầu với Next.js 15, bạn chỉ cần một dòng lệnh:

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

Trong quá trình cài đặt, bạn sẽ được hỏi một số câu hỏi:

 Would you like to use TypeScript? Yes
 Would you like to use ESLint? Yes
 Would you like to use Tailwind CSS? Yes
 Would you like to use `src/` directory? No
 Would you like to use App Router? Yes
 Would you like to customize the default import alias? No

Khuyến nghị: Chọn TypeScript và App Router để tận dụng tối đa các tính năng mới.

Tạo trang đầu tiên

Sau khi cài đặt xong, cấu trúc project sẽ như sau:

my-next-app/
├── app/
│   ├── layout.tsx      # Root layout
│   ├── page.tsx        # Home page
│   └── globals.css     # Global styles
├── public/             # Static assets
├── package.json
└── next.config.ts

Hãy tạo một trang "About" đơn giản:

// app/about/page.tsx
export default function AboutPage() {
  return (
    <div className="container mx-auto px-4 py-8">
      <h1 className="text-4xl font-bold mb-4">About Us</h1>
      <p className="text-lg text-gray-700">
        Welcome to our Next.js 15 application!
      </p>
    </div>
  );
}

Để truy cập trang này, chỉ cần mở http://localhost:3000/about - Next.js tự động tạo route dựa trên cấu trúc thư mục.

Fetch Data với Server Component

Một trong những điểm mạnh của Server Components là khả năng fetch data trực tiếp:

// app/users/page.tsx
interface User {
  id: number;
  name: string;
  email: string;
}
 
async function getUsers(): Promise<User[]> {
  const res = await fetch('https://jsonplaceholder.typicode.com/users', {
    // Cache data trong 1 giờ
    next: { revalidate: 3600 }
  });
  
  if (!res.ok) {
    throw new Error('Failed to fetch users');
  }
  
  return res.json();
}
 
export default async function UsersPage() {
  const users = await getUsers();
  
  return (
    <div className="container mx-auto px-4 py-8">
      <h1 className="text-3xl font-bold mb-6">Users</h1>
      <div className="grid gap-4">
        {users.map((user) => (
          <div key={user.id} className="p-4 border rounded-lg">
            <h2 className="text-xl font-semibold">{user.name}</h2>
            <p className="text-gray-600">{user.email}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

Tạo Form với Server Action

Xây dựng một contact form hoàn chỉnh:

// app/contact/actions.ts
'use server';
 
export async function submitContactForm(formData: FormData) {
  const name = formData.get('name') as string;
  const email = formData.get('email') as string;
  const message = formData.get('message') as string;
  
  // Validation
  if (!name || !email || !message) {
    return { 
      success: false, 
      error: 'All fields are required' 
    };
  }
  
  // Email validation
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(email)) {
    return { 
      success: false, 
      error: 'Invalid email address' 
    };
  }
  
  try {
    // Send email hoặc save to database
    console.log('Contact form submitted:', { name, email, message });
    
    return { 
      success: true, 
      message: 'Thank you for contacting us!' 
    };
  } catch (error) {
    return { 
      success: false, 
      error: 'Failed to submit form. Please try again.' 
    };
  }
}
// app/contact/page.tsx
import { submitContactForm } from './actions';
 
export default function ContactPage() {
  return (
    <div className="container mx-auto px-4 py-8 max-w-2xl">
      <h1 className="text-3xl font-bold mb-6">Contact Us</h1>
      
      <form action={submitContactForm} className="space-y-4">
        <div>
          <label htmlFor="name" className="block mb-2 font-medium">
            Name
          </label>
          <input
            type="text"
            id="name"
            name="name"
            required
            className="w-full px-4 py-2 border rounded-lg"
          />
        </div>
        
        <div>
          <label htmlFor="email" className="block mb-2 font-medium">
            Email
          </label>
          <input
            type="email"
            id="email"
            name="email"
            required
            className="w-full px-4 py-2 border rounded-lg"
          />
        </div>
        
        <div>
          <label htmlFor="message" className="block mb-2 font-medium">
            Message
          </label>
          <textarea
            id="message"
            name="message"
            rows={5}
            required
            className="w-full px-4 py-2 border rounded-lg"
          />
        </div>
        
        <button
          type="submit"
          className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
        >
          Send Message
        </button>
      </form>
    </div>
  );
}

Best Practices

1. Khi nào dùng Server Components

Server Components là default và nên được sử dụng khi:

  • Data Fetching: Fetch data từ database hoặc API
  • Backend Logic: Xử lý business logic phức tạp
  • Security: Code chứa sensitive information
  • Large Dependencies: Sử dụng libraries lớn (chỉ chạy trên server)
// Sử dụng Server Component (default)
async function ProductList() {
  const products = await fetchProducts(); // Fetch trực tiếp
  return <div>{/* Render products */}</div>;
}

2. Khi nào dùng Client Components

Client Components cần thiết khi:

  • Interactivity: Sử dụng event listeners (onClick, onChange, etc.)
  • Browser APIs: Cần truy cập window, localStorage, etc.
  • React Hooks: useState, useEffect, useContext
  • Real-time Updates: WebSocket connections
'use client'; // Khai báo Client Component
 
import { useState } from 'react';
 
export function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}

3. Error Handling

Next.js 15 cung cấp error boundaries tích hợp:

// app/error.tsx
'use client';
 
export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen">
      <h2 className="text-2xl font-bold mb-4">Something went wrong!</h2>
      <p className="text-gray-600 mb-4">{error.message}</p>
      <button
        onClick={reset}
        className="px-4 py-2 bg-blue-600 text-white rounded"
      >
        Try again
      </button>
    </div>
  );
}

4. TypeScript Setup

Tận dụng TypeScript để có type safety tốt hơn:

// types/index.ts
export interface Post {
  id: string;
  title: string;
  content: string;
  author: {
    name: string;
    email: string;
  };
  createdAt: Date;
  tags: string[];
}
 
// app/blog/[id]/page.tsx
import type { Post } from '@/types';
 
async function getPost(id: string): Promise<Post> {
  // Fetch post với type safety
  const res = await fetch(`/api/posts/${id}`);
  return res.json();
}

Kết luận

Next.js 15 đại diện cho một bước tiến lớn trong việc xây dựng web applications hiện đại. Với App Router, React Server Components, Server Actions, và Turbopack, framework này cung cấp một bộ công cụ mạnh mẽ để xây dựng ứng dụng có hiệu suất cao và trải nghiệm phát triển tuyệt vời.

Những điểm chính cần nhớ:

  • App Router: Kiến trúc routing mới với folder-based organization
  • Server Components: Giảm bundle size và cải thiện performance
  • Server Actions: Đơn giản hóa việc xử lý forms và mutations
  • Turbopack: Build và hot reload nhanh hơn đáng kể

Bước tiếp theo

Để tiếp tục hành trình học Next.js 15:

  1. Thực hành: Tạo một dự án nhỏ để làm quen với các concepts
  2. Đọc Documentation: Next.js Official Docs
  3. Khám phá Advanced Features: Middleware, Internationalization, Analytics
  4. Join Community: Next.js Discord

Resources bổ sung


Có câu hỏi? Hãy để lại comment bên dưới hoặc liên hệ qua email. Chúc bạn thành công với Next.js 15!

Cong Dinh

Cong Dinh

Technology Consultant | Trainer | Solution Architect

Với hơn 10 năm kinh nghiệm trong phát triển web và cloud architecture, tôi giúp doanh nghiệp xây dựng giải pháp công nghệ hiện đại và bền vững. Chuyên môn: Next.js, TypeScript, AWS, và Solution Architecture.

Bài viết liên quan