Yugen UI

Trang trạng thái HTTP

404, 500, bảo trì, mất mạng: khi cả trang không hiện được, nói rõ chuyện gì xảy ra, chỉ một việc nên làm tiếp và tự khôi phục khi có thể, trong cùng bố cục với màn chờ khởi động.

Khi nào cần trang riêng

Trang trạng thái thay cả vùng nội dung chính, nên chỉ dùng khi cả route không hiện được: đường dẫn không có trang, không có quyền, máy chủ lỗi, mất mạng lúc mở trang. Một phần của trang lỗi thì báo ngay tại phần đó, phần còn lại vẫn dùng được.

Tình huốngDùng
Cả route không render đượcTrang trạng thái
Một vùng tải lỗi (bảng, biểu đồ)ErrorState trong vùng đó, có nút thử lại
Gửi form lỗiLỗi ở từng field hoặc MessageBar; giữ nguyên dữ liệu đã nhập
Lỗi ngắn, tự hếtToast hoặc MessageBar

Phòng thử

Mười một trạng thái trong cùng bố cục với màn chờ khởi động. Đổi kiểu số (Kanji / Latin), chạy lại, hoặc xem toàn màn hình rồi chuyển trạng thái bằng nút trước / sau.

Không tìm thấy trang

Không có trang ở đường dẫn này.

Danh mục trạng thái

MãTiêu đềKhi nàoHành động chính
400Yêu cầu không hợp lệTham số trong URL hoặc dữ liệu gửi lên sai dạng, người dùng không sửa được tại chỗ.Quay lại
401Cần đăng nhậpChưa đăng nhập hoặc phiên đã hết hạn.Đăng nhập
403Không có quyền truy cậpĐã đăng nhập nhưng thiếu quyền.Xin quyền truy cập
404Không tìm thấy trangKhông có trang ở đường dẫn này.Tìm kiếm
410Trang này đã bị gỡTrang bị gỡ có chủ đích; biết chỗ thay thế thì dẫn tới đó.Tới trang mới
429Bạn thao tác hơi nhanhVượt giới hạn số yêu cầu; thời gian chờ lấy từ header Retry-After.Thử lại
500Máy chủ gặp lỗiLỗi không lường trước ở máy chủ, kể cả 502 từ cổng trung gian.Thử lại
503Đang bảo trìBảo trì có kế hoạch hoặc quá tải tạm thời; có Retry-After thì đếm ngược.Tải lại
504Máy chủ phản hồi quá lâuHết thời gian chờ ở máy chủ (504) hoặc ở trình duyệt (408).Thử lại
Ngoại tuyếnKhông có kết nối mạngTrình duyệt mất mạng hoặc yêu cầu lỗi mạng; nghe sự kiện online để tự thử lại.Thử lại
Bản mớiĐã có phiên bản mớiNạp file JS lỗi sau một lần deploy (tab mở từ trước, tên file đã đổi).Tải lại

Viết nội dung

Tiêu đề nói chuyện gì xảy ra bằng lời thường (“Không tìm thấy trang”), mô tả nói vì sao nếu biết và người dùng làm được gì tiếp. Mã nằm ở dòng nhỏ phía trên tiêu đề cho ai cần báo lỗi, không bao giờ là chữ duy nhất trên trang.

Không đổ lỗi cho người dùng, không đùa khi họ vừa mất việc đang làm, không in stack trace. Mã để tra lỗi (7f3a-91c2) là chữ thường, chọn và sao chép được.

Mỗi trang có đúng một hành động chính; hành động phụ là lối ra an toàn như về trang chủ hay đổi tài khoản.

Logo & mã viết dọc

Logo ở góc đổi theo trạng thái: thiếu một cánh khi không tìm thấy trang, rụng hết khi trang đã bị gỡ, còn là nụ khi cần đăng nhập hoặc xin quyền, mực đứt khi máy chủ lỗi, nhạt khi hết thời gian chờ, chỉ còn vệt mờ khi mất mạng. Ở 429 và 503, nét cọ đầy dần theo thời gian chờ; hết giờ thì hoa nở cùng lúc nút Thử lại bật.

Kiểu Kanji: mã viết dọc ở mép như màn chờ, đọc từng chữ số (四〇四); trạng thái không có mã dùng chữ: 圏外 (ngoài vùng phủ sóng) khi mất mạng, 新版 khi có bản mới. Kiểu Latin cho sản phẩm không dùng chữ Hán: mã nằm ngang, nét mảnh ở góc trên; trạng thái không có mã thì để trống góc đó.

Tự khôi phục

Trạng thái tạm thời phải tự hết: đếm ngược theo Retry-After rồi bật nút, nghe sự kiện online để thử lại khi có mạng, nạp file JS lỗi sau deploy thì mời tải lại. Đăng nhập xong (401) thì đưa người dùng về đúng trang họ định mở.

// 429 / 503: thời gian chờ lấy từ header, không đoán
const wait = Number(response.headers.get("Retry-After")) || 30;

// Mất mạng: thử lại khi trình duyệt báo có mạng
window.addEventListener("online", retry, { once: true });

// Bản mới: file JS của route không còn sau một lần deploy
const Settings = lazy(() => import("./pages/Settings").catch(() => ({ default: NewVersionPage })));

Trang 404 cần trả mã 404 thật và có noindex, để công cụ tìm kiếm không lập chỉ mục một trang trông như bình thường. Host tĩnh (GitHub Pages) chỉ trả được 404.html; 500 và 503 khi đó do app tự hiện.

Khả năng tiếp cận

Tiêu đề là h1 nói tên trạng thái; chuyển trang phía client thì đưa focus tới h1 và cập nhật document.title. Mã viết dọc là trang trí (aria-hidden); mã đọc được nằm ở dòng phía trên tiêu đề.

Đếm ngược báo qua live region polite theo từng quãng (10 giây), không phải mỗi giây. Không tự tải lại mà không nói trước. Khi giảm chuyển động, nét cọ có sẵn và cánh hoa nằm sẵn dưới đất thay vì rơi.

Nên & không nên

Nên
  • Nói chuyện gì xảy ra bằng lời thường, kèm mã ở dòng phụ.
  • Một hành động chính, một lối ra an toàn.
  • Đếm ngược theo Retry-After, thử lại khi có mạng.
  • Trả mã HTTP thật và noindex cho trang 404.
Không nên
  • Chuyển đường dẫn lạ về trang chủ như không có gì xảy ra.
  • Chỉ hiện “404” hay “Error” mà không giải thích.
  • In stack trace hoặc thông báo kỹ thuật cho người dùng.
  • Tự tải lại liên tục khi máy chủ vẫn đang lỗi.