Hướng dẫn

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 functionThiếu import, biến hoặc cài đặtBướ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ì JavaScriptBước 2
Uncaught SyntaxError: Unexpected token '<'Cùng nguyên nhân: HTML xuất hiện nơi lẽ ra là JavaScriptBước 2
supabaseUrl is required, Missing API key, hoặc tương tựMột biến môi trường bị rỗngBước 3
Access to fetch ... has been blocked by CORS policyMột yêu cầu đến miền khác bị chặnXem cách sửa lỗi CORS
Không có lỗi nàoRender đã chạy nhưng không hiển thị gì, hoặc CSS đang ẩn nội dungBướ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ính index.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 qua import.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 .env mà 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.name trước khi user về 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ư window hoặc localStorage trong 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ại ProjectList.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.html có id="app" nhưng code tìm root, 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ư analytics hoặc ads.

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/.css bị 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ứ.

Mythex · Pricing · Xây dựng mọi thứ với AI · Mẫu website và ứng dụng · So sánh Mythex · Thuật ngữ xây dựng ứng dụng bằng AI · Công cụ miễn phí để xây dựng ứng dụng bằng AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو 简体中文 繁體中文(香港) 繁體中文(台灣)