Xây dựng Dark Mode trong Next.js mà không bị hiện tượng nhấp nháy
Dark mode có vẻ đơn giản. Cho đến khi bạn thấy hiện tượng nhấp nháy.
Khi người dùng tải trang, máy chủ sẽ gửi giao diện mặc định. Người dùng sẽ thấy một màn hình trắng trong tích tắc trước khi giao diện tối được áp dụng. Đây là một trải nghiệm người dùng kém.
Vấn đề này xảy ra vì máy chủ không thể đọc được localStorage. Máy chủ chỉ biết được giao diện sau khi trình duyệt chạy JavaScript của bạn.
Đây là cách khắc phục.
Giải pháp: Inline Script
Bạn phải áp dụng giao diện trước khi React khởi chạy. Hãy đặt một đoạn script nhỏ trong thẻ <head>. Đoạn script này sẽ đọc tùy chọn của người dùng và thêm class dark ngay lập tức.
Sử dụng các bước sau:
- Thêm một script vào
<head>của RootLayout để kiểm tralocalStorage. - Sử dụng
suppressHydrationWarningtrên thẻ<html>. Điều này giúp ngăn React báo lỗi về sự không đồng nhất giữa các giao diện (mismatch). - Sử dụng
ThemeProviderđể quản lý state và đồng bộ vớilocalStorage. - Sử dụng CSS variables với Tailwind để có các hiệu ứng chuyển đổi màu sắc mượt mà.
Tại sao cách này hiệu quả: Đoạn script chạy trước khi trang được render. Nó ngăn chặn hiện tượng nhảy giao diện (visual jump).
Xử lý hình ảnh
Hình ảnh thường cần các phiên bản khác nhau cho chế độ sáng và tối. Bạn có hai lựa chọn:
- Phương pháp CSS: Sử dụng
display: nonevàdisplay: blockđể tráo đổi hình ảnh dựa trên class.dark. Đây là cách nhanh nhất. - Phương pháp Client: Sử dụng một component để kiểm tra giao diện và chọn nguồn ảnh phù hợp.
Mẹo chuyên nghiệp cho nội dung phía Server
Nếu bạn cần máy chủ biết được giao diện để hiển thị biểu đồ hoặc các nội dung nặng, hãy sử dụng cookies thay vì localStorage.
- Lưu giao diện vào một cookie.
- Sử dụng Next.js middleware để đọc cookie đó.
- Truyền giao diện vào layout thông qua headers.
Điều này cho phép máy chủ gửi HTML chính xác ngay từ đầu.
Tóm tắt để có một hệ thống không bị nhấp nháy:
• Sử dụng inline script trong <head>
• Sử dụng suppressHydrationWarning
• Quản lý state với một Context Provider
• Lắng nghe các thay đổi tùy chọn của hệ thống
Cách tiếp cận này phù hợp cho các ứng dụng production. Nó đảm bảo việc chuyển đổi tức thì và không hề bị nhấp nháy.