Cách sửa trang trắng trong web app
Trang trắng gần như luôn có nghĩa là một trong hai điều: JavaScript của app bị crash trước khi vẽ bất cứ thứ gì, hoặc JavaScript chưa bao giờ tải được. Mở console của trình duyệt (chuột phải → Inspect → Console), đọc lỗi đỏ đầu tiên, rồi kiểm tra tab Network để tìm các file không tải được. Phần lớn nguyên nhân là thiếu biến môi trường, base path sai, build chưa xong, hoặc một component bị crash.
Hướng dẫn này áp dụng cho các single-page app xây dựng bằng React, Vue hoặc tương tự (bao gồm các app do công cụ AI tạo), nơi trang trắng gặp nhiều nhất.
Vì sao trang bị trắng
Một single-page app (SPA) hiện đại gửi cho trình duyệt một file HTML gần như trống, gần giống thế này:
<body>
<div id="root"></div>
<script type="module" src="/assets/index-a1b2c3.js"></script>
</body>
Sau đó JavaScript xây dựng toàn bộ trang bên trong div trống đó. Nếu script không tải được, hoặc ném lỗi trước khi render, div vẫn trống và bạn thấy màu trắng. Trang không "hỏng" theo cách nhìn thấy được; nó chỉ không bao giờ được vẽ ra.
Đó là lý do việc sửa luôn bắt đầu từ công cụ phát triển, không phải từ chính trang.
Bước 1: Đọc console
Mở công cụ phát triển: chuột phải vào trang và chọn Inspect, hoặc nhấn F12 (Cmd+Option+I trên Mac). Vào tab Console và tải lại trang.
Hãy nhìn lỗi đỏ đầu tiên; các lỗi sau thường chỉ là hệ quả. Nội dung của nó chỉ ra nguyên nhân:
| Thông báo trong console (cách diễn đạt thường gặp) | Nghĩa là | Đi đến |
|---|---|---|
Cannot read properties of undefined (reading '...') | Code mong đợi dữ liệu nhưng không có | Bước 4 |
... is not defined / ... is not a function | Thiếu import, biến hoặc cài đặt | Bước 4 hoặc Bước 3 |
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html" | URL của một script trả về trang HTML thay vì JavaScript | Bước 2 |
Uncaught SyntaxError: Unexpected token '<' | Cùng nguyên nhân: HTML xuất hiện nơi lẽ ra là JavaScript | Bước 2 |
supabaseUrl is required, Missing API key, hoặc tương tự | Một biến môi trường bị rỗng | Bước 3 |
Access to fetch ... has been blocked by CORS policy | Một yêu cầu đến miền khác bị chặn | Xem cách sửa lỗi CORS |
| Không có lỗi nào | Render đã chạy nhưng không hiển thị gì, hoặc CSS đang ẩn nội dung | Bước 6 |
Sao chép toàn bộ nội dung lỗi, bao gồm tên file và số dòng. Nếu bạn đang dùng công cụ AI tạo app, hãy dán thẳng vào chat.
Bước 2: Kiểm tra các file đã tải chưa
Mở tab Network, chọn Disable cache, rồi tải lại. Xem các yêu cầu tới file .js và .css.
- Trạng thái 404 trên một file JavaScript: trang đang yêu cầu một file không có trên máy chủ.
- Trạng thái 200 nhưng kiểu là
text/html: máy chủ trả về một trang (thường là chínhindex.html, do fallback SPA) thay vì script. Nguyên nhân gốc giống nhau: file không nằm ở nơi trang mong đợi.
Các lý do thường gặp:
Base path sai. Nếu app được phục vụ từ một thư mục con, như example.com/app/, nhưng được build để tải file từ /assets/..., mọi yêu cầu script đều trượt. Trong Vite đây là tùy chọn base trong vite.config; trong Create React App là trường homepage; trong Next.js là basePath. Nó phải khớp với nơi app thật sự được phục vụ.
index.html cũ. Các công cụ build đặt cho file tên có mã hash theo nội dung, như index-a1b2c3.js. Sau khi deploy phiên bản mới, file cũ biến mất. Nếu trình duyệt hoặc CDN vẫn còn index.html cũ trong cache, nó sẽ yêu cầu file cũ và không nhận được gì. Hard refresh (Cmd+Shift+R hoặc Ctrl+Shift+R) sẽ xác nhận điều này. Cách sửa lâu dài là phục vụ index.html với header cache ngắn hoặc không cache, trong khi các file có hash được cache lâu.
Build chưa xong hoặc chưa được deploy. Nếu build thất bại, host có thể đang phục vụ một thư mục đầu ra cũ hoặc trống. Hãy kiểm tra log build để tìm lỗi.
Publish sai thư mục. Host phải phục vụ kết quả build (thường là dist hoặc build), không phải thư mục mã nguồn của dự án. Nếu phục vụ mã nguồn, bạn sẽ có một index.html trỏ đến /src/main.tsx, mà trình duyệt không thể chạy.
Bước 3: Kiểm tra biến môi trường
Các app front end thường đọc những cài đặt như URL API hoặc khóa công khai vào lúc build. Nếu một biến bị thiếu trên bản build trực tiếp, code như createClient(undefined, undefined) sẽ ném lỗi ngay lập tức, và trang bị trắng.
Điều cần biết:
- Trong Vite, chỉ các biến có tiền tố
VITE_mới có sẵn trong code trình duyệt, đọc quaimport.meta.env.VITE_NAME. Trong Create React App làREACT_APP_; trong Next.js làNEXT_PUBLIC_. - Các giá trị này được nhúng vào lúc build. Thêm biến sau khi build sẽ không có tác dụng cho đến khi bạn build và deploy lại.
- Máy cục bộ hoặc bản xem trước có thể có file
.envmà bản build production không có. Hãy đặt các biến tương tự trên host. - Mọi thứ có các tiền tố này đều nằm trong JavaScript công khai. Chỉ đặt giá trị công khai ở đó, không bao giờ đặt khóa bí mật.
Một cách kiểm tra nhanh: tìm undefined gần tên một cài đặt trong lỗi console, hoặc hỏi:
Trang đã publish hiện trang trắng. Liệt kê mọi biến môi trường mà frontend đọc, kiểm tra biến nào bị thiếu hoặc rỗng trong bản build trực tiếp, và làm cho app hiển thị một thông báo lỗi rõ ràng thay vì trang trắng khi thiếu biến.
Bước 4: Sửa lỗi crash
Nếu console hiện một lỗi JavaScript bình thường, code đã crash trong lúc render. Các nguyên nhân điển hình trong app do AI xây dựng:
- Dữ liệu chưa tải xong. Một component đọc
user.nametrước khiuservề tới nơi. Cách sửa là trạng thái đang tải, hoặc optional chaining (user?.name). - Dữ liệu rỗng. Một tài khoản mới chưa có bản ghi nào, và code giả định danh sách có ít nhất một mục.
- Cấu trúc dữ liệu không như mong đợi. Một API trả về một object lỗi thay vì danh sách mà code cần.
- Thiếu import sau khi một file bị đổi tên hoặc di chuyển.
- Dùng API chỉ có trong trình duyệt khi render phía máy chủ, như
windowhoặclocalStoragetrong một server component của Next.js.
Hãy đưa cho AI toàn bộ lỗi, trang đó, và bạn đã đăng nhập bằng tài khoản nào:
Trang Dashboard trắng với người dùng mới. Console:
TypeError: Cannot read properties of undefined (reading 'map')tạiProjectList.tsx:18. Nó chạy được với tài khoản của tôi, tài khoản có dự án. Hãy sửa để tài khoản trống hiển thị "Chưa có dự án nào", và kiểm tra một tài khoản mới trong bản xem trước.
Bước 5: Thêm error boundary
Trong React, một component bị crash có thể gỡ bỏ toàn bộ app, đó là lý do một lỗi nhỏ tạo ra một trang hoàn toàn trắng. Error boundary là một component bắt các lỗi render bên dưới nó và hiển thị một phương án dự phòng.
Thêm một error boundary quanh các route chính, hiển thị "Đã xảy ra lỗi" kèm nút Tải lại, và ghi lỗi vào console. Giữ header và thanh điều hướng nằm ngoài boundary để chúng vẫn hiển thị.
Nó không sửa được lỗi, nhưng khách truy cập thấy một thông báo thay vì màn hình trắng, và bạn biết chỗ nào bị hỏng.
Bước 6: Không có lỗi nhưng vẫn trắng
Nếu console sạch và script tải thành công:
- Kiểm tra tab Elements. Có nội dung bên trong
<div id="root">không? Nếu có, trang đang render nhưng vô hình: chữ trắng trên nền trắng,opacity: 0,display: none, hoặc một phần tử toàn màn hình che lên. - Kiểm tra router. Nếu không có route nào khớp với URL hiện tại và không có route "không tìm thấy", một số router không render gì. Thêm một route bắt tất cả hiển thị trang 404.
- Kiểm tra điểm gắn kết (mount). Code phải gắn vào một phần tử thật sự tồn tại. Nếu
index.htmlcóid="app"nhưng code tìmroot, sẽ không có gì hiện ra (và React thường ghi một lỗi). - Kiểm tra tiện ích trình duyệt. Thử cửa sổ ẩn danh. Trình chặn quảng cáo đôi khi chặn các script có tên như
analyticshoặcads.
Chỉ trắng sau khi tải lại trang?
Nếu trang chủ chạy được nhưng tải lại /dashboard lại hiện trang trắng hoặc 404, máy chủ không biết phải gửi index.html cho các route của app. Đó là vấn đề fallback định tuyến, được trình bày trong cách sửa lỗi 404 sau khi deploy.
Lỗi thường gặp
- Đọc lỗi cuối cùng thay vì lỗi đầu tiên. Dòng đỏ đầu tiên thường là nguyên nhân.
- Đặt biến môi trường mà không build lại. Biến của frontend được cố định lúc build.
- Chỉ kiểm tra bằng tài khoản của chính mình. Crash với tài khoản trống là một trong những nguyên nhân trang trắng phổ biến nhất.
- Giả định việc deploy đã thành công. Hãy kiểm tra log build trước khi gỡ lỗi code.
- Đổ lỗi cho cache trình duyệt mọi thứ. Một hard refresh loại trừ điều đó trong vài giây; nếu trang vẫn trắng, nguyên nhân nằm ở chỗ khác.
Trang trắng trong Mythex
Nếu Preview trắng, trước tiên hãy kiểm tra app đang chạy (mở Code → terminal), rồi yêu cầu Mythex khởi động đúng server, nhấn Refresh trên thanh công cụ của bản xem trước, hoặc dùng /fix. Với một URL đã publish bị trắng, tài liệu gợi ý chờ một phút rồi hard-refresh, xác nhận biến môi trường và cơ sở dữ liệu đã được thiết lập trước khi publish, và kiểm tra hạn mức hosting. Hãy nhớ rằng app đã publish là một bản chụp: sau khi sửa, hãy publish lại. Nếu một thay đổi gây ra lỗi, Revert to this point ở câu trả lời tốt cuối cùng sẽ khôi phục dự án. Xem Xử lý sự cố và Xử lý sự cố khi publish trong tài liệu, và hướng dẫn chung của chúng tôi về gỡ lỗi app do AI xây dựng.
Danh sách kiểm tra trang trắng
- Đã đọc lỗi đỏ đầu tiên trong Console
- Đã kiểm tra tab Network tìm các file
.js/.cssbị 404 hoặc trả về HTML - Base path khớp với nơi app được phục vụ
- Build đã xong, và thư mục kết quả build là thứ được publish
- Mọi biến môi trường của frontend đã được đặt trên bản build trực tiếp, sau đó đã build lại
- Đã sửa crash, kể cả với tài khoản trống và tài khoản mới
- Có error boundary để các lỗi sau này hiển thị một thông báo
- Có route bắt tất cả cho các URL không tồn tại
- Đã kiểm tra sau một hard refresh và trong cửa sổ ẩn danh
Câu hỏi thường gặp
Vì sao app React của tôi hiện trang trắng?
Thường là vì JavaScript bị crash trước khi kịp render gì, hoặc file JavaScript chưa bao giờ tải được. Mở console của trình duyệt: lỗi đỏ ở đó cho bạn biết là loại nào, cùng file và dòng xảy ra lỗi.
Vì sao app chạy được ở máy tôi nhưng sau khi deploy lại hiện trang trắng?
Các nguyên nhân phổ biến nhất là biến môi trường chưa được đặt cho bản build trực tiếp, file JavaScript và CSS được yêu cầu từ đường dẫn sai (lệch base path), và một index.html bị cache cũ trỏ đến các file không còn tồn tại.
'Failed to load module script' nghĩa là gì?
Trình duyệt đã yêu cầu một file JavaScript nhưng nhận về một trang HTML, thường là index.html của site hoặc một trang lỗi. Đường dẫn file sai hoặc file không tồn tại trên máy chủ, vì vậy hãy kiểm tra kết quả build và cài đặt base path của app.
Làm sao để một lỗi không làm trắng toàn bộ trang?
Thêm một error boundary. Trong React, error boundary là một component bắt các lỗi render trong phần trang nằm bên dưới nó và hiển thị một thông báo dự phòng thay vì gỡ bỏ mọi thứ.