Hướng dẫn

Cách sửa lỗi 404 sau khi triển khai website hoặc app

Nếu app của bạn chạy tốt ở máy nhưng các trang trả về 404 sau khi deploy, nguyên nhân phổ biến nhất là thiếu định tuyến cho single-page app (SPA): máy chủ tìm một file tên /dashboard không tồn tại, vì route đó chỉ tồn tại trong JavaScript. Cách sửa là một quy tắc fallback phục vụ index.html cho các route của app. Các nguyên nhân khác gồm file thiếu trong kết quả build, đường dẫn phân biệt hoa thường, khác biệt về dấu gạch chéo cuối, base path sai, và các route API chưa được deploy.

Hãy bắt đầu bằng việc ghi lại chính xác URL nào bị 404 và bạn đã đến đó bằng cách nào. Mẫu hình đó sẽ chỉ thẳng vào nguyên nhân.

Bước 1: Tìm mẫu hình

Bạn thấy gìNguyên nhân có khả năng nhấtXem
Trang chủ hoạt động; bấm liên kết chạy được; nhưng tải lại hoặc mở liên kết sâu thì 404Thiếu fallback SPABước 2
Mọi trang đều 404, kể cả trang chủSai thư mục được publish, hoặc build không được deployBước 3
Trang tải được, nhưng hình ảnh, font hoặc script bị 404File thiếu trong build, hoặc đường dẫn saiBước 4
Chạy với /about/, lỗi với /about (hoặc ngược lại)Cách xử lý dấu gạch chéo cuốiBước 5
/About lỗi nhưng /about chạy đượcMáy chủ phân biệt hoa thườngBước 4
Trang tải được, nhưng các yêu cầu dữ liệu /api/... bị 404API chưa deploy hoặc chưa được định tuyếnBước 6
URL cũ từ một site trước đó bị 404Thiếu chuyển hướngBước 7
Chỉ xảy ra trên tên miền riêngThiết lập DNS hoặc tên miềnBước 8

Để thấy mã trạng thái thật, mở công cụ phát triển (chuột phải → Inspect), vào tab Network, tải lại, và xem trạng thái của yêu cầu đầu tiên.

Bước 2: Thêm fallback SPA

Đây là lỗi kinh điển. Trong một single-page app React, Vue hay Svelte, máy chủ chỉ có một số ít file thật: index.html và vài file JavaScript, CSS. Các route như /dashboard hoặc /projects/42 được xử lý bởi router trong trình duyệt.

  • Bấm vào liên kết chạy được: router đổi URL và vẽ trang mới mà không cần hỏi máy chủ.
  • Tải lại hoặc mở liên kết trực tiếp thất bại: trình duyệt hỏi máy chủ /dashboard, máy chủ không có file đó, và trả về 404.

Cách sửa là một quy tắc nói: nếu yêu cầu không khớp với file thật nào, hãy phục vụ index.html với trạng thái 200 và để router tiếp quản. Cách thêm tùy thuộc vào host (kiểm tra tài liệu hiện tại của host, vì chi tiết thay đổi):

HostQuy tắc fallback thường dùng
NetlifyMột file _redirects trong thư mục được publish với dòng /* /index.html 200
VercelMột rewrite trong vercel.json từ mọi đường dẫn đến /index.html (các preset framework thường tự xử lý)
Cloudflare PagesMặc định phục vụ fallback kiểu SPA khi không có 404.html ở cấp cao nhất
Nginxtry_files $uri $uri/ /index.html; trong khối location /
ApacheMột quy tắc rewrite trong .htaccess gửi các yêu cầu không phải file đến index.html
GitHub PagesKhông có rewrite phía máy chủ; cách thay thế phổ biến là định tuyến bằng hash hoặc một 404.html chuyển hướng

Đảm bảo quy tắc không nuốt các file thật: yêu cầu /assets/app.js vẫn phải trả về file JavaScript. Nếu chúng trả về index.html, bạn sẽ gặp trang trắng với lỗi "Failed to load module script". Xem cách sửa trang trắng.

Cũng hãy thêm một route bắt tất cả cho router để các URL không khớp trang nào hiển thị trang "Không tìm thấy" thân thiện thay vì trống.

Nếu bạn không thể thay đổi cấu hình máy chủ, định tuyến bằng hash (URL như /#/dashboard) tránh được vấn đề, vì phần sau # không bao giờ được gửi đến máy chủ. Đây là giải pháp thay thế chứ không phải lựa chọn đầu tiên: URL kém đẹp hơn và kém thân thiện với công cụ tìm kiếm.

Các framework render trang trên máy chủ hoặc tạo trang lúc build (Next.js, Astro và tương tự) thường có file thật hoặc route máy chủ cho từng trang, nên vấn đề này ít gặp hơn ở đó. Tương đương của họ là một trang không được tạo lúc build.

Bước 3: Kiểm tra những gì thực sự được deploy

Nếu mọi thứ đều 404, có lẽ máy chủ không phục vụ app đã build của bạn.

  • Đúng thư mục. Host phải publish kết quả build (thường là dist với Vite, build với Create React App, out với export tĩnh Next.js), không phải thư mục gốc của dự án.
  • Build đã chạy. Đọc log deploy. Nếu build thất bại, host có thể không deploy gì, hoặc vẫn dùng phiên bản cũ.
  • index.html nằm ở cấp cao nhất của thư mục được publish, không nằm trong thư mục con.
  • Base path khớp. Nếu app được phục vụ từ example.com/app/, nó phải được build với base đó (base của Vite, basename của React Router), nếu không mọi route và tài nguyên đều không tìm thấy.

Bước 4: Sửa file thiếu và đường dẫn sai

Khi trang tải được nhưng tài nguyên bị 404:

  • Phân biệt hoa thường. macOS và Windows thường coi Logo.png và logo.png là cùng một file. Hầu hết máy chủ Linux thì không. Hãy làm cho mọi tham chiếu khớp chính xác với tên file thật.
  • File nằm ngoài build. Trong Vite, các file trong public/ được sao chép nguyên và được tham chiếu từ gốc (/logo.png). File được import trong code sẽ được gói vào bundle. Một file nằm ở nơi khác trong dự án có thể hoàn toàn không được deploy.
  • Đường dẫn tương đối. images/photo.jpg được phân giải theo URL hiện tại, nên nó hỏng trên /blog/post-1. Hãy dùng /images/photo.jpg.
  • File tải lên được lưu vào đĩa cục bộ. Nếu file của người dùng được ghi vào thư mục riêng của máy chủ, chúng sẽ mất khi có phiên bản mới được deploy. Hãy dùng lưu trữ file đúng cách.

Bước 5: Xử lý dấu gạch chéo cuối nhất quán

/about và /about/ là hai URL khác nhau. Các host khác nhau về việc thêm hay bớt dấu gạch chéo, và sự không khớp với liên kết hoặc router của bạn có thể gây ra 404 hoặc vòng lặp chuyển hướng. Hãy chọn một kiểu, làm cho liên kết của bạn dùng kiểu đó, và cấu hình host để chuyển hướng dạng còn lại về nó. Tính nhất quán cũng giúp công cụ tìm kiếm, vì nếu không chúng có thể thấy hai bản sao của mỗi trang.

Bước 6: Sửa các route API bị 404

Nếu trang tải được nhưng tab Network cho thấy các yêu cầu /api/... trả về 404:

  • Back end chưa được deploy. Host tĩnh chỉ phục vụ file; back end phải chạy ở đâu đó.
  • Đường dẫn được định tuyến khác trên production. Khi phát triển, một proxy có thể đã chuyển /api đến một máy chủ riêng. Trên production, host cần một rewrite tương đương, hoặc front end phải gọi đến địa chỉ thật của API.
  • Fallback SPA bắt nhầm. Một yêu cầu API trả về index.html với trạng thái 200 có nghĩa là quy tắc fallback quá rộng. Hãy loại trừ /api/* khỏi nó.

Các yêu cầu của app đã publish tới /api/orders trả về 404, nhưng chúng chạy được trong bản xem trước. Hãy kiểm tra cách /api được định tuyến trong bản xem trước và trong app đã publish, rồi làm cho front end trên production kết nối đến back end theo cùng cách.

Bước 7: Chuyển hướng các URL cũ

Nếu bạn đã chuyển từ một site khác hoặc tái cấu trúc, các URL cũ mà người dùng và công cụ tìm kiếm vẫn dùng sẽ bị 404. Hãy thêm một chuyển hướng 301 (vĩnh viễn) từ mỗi URL cũ đến vị trí mới. Giữ một danh sách và kiểm thử một mẫu sau khi ra mắt. Hướng dẫn của chúng tôi về chuyển một site WordPress trình bày cách lập danh sách đó.

Bước 8: Kiểm tra tên miền

Nếu app chạy ở địa chỉ của host nhưng báo 404 trên tên miền riêng, tên miền có thể đang trỏ đến sai dự án, hoặc host chưa gắn tên miền vào site của bạn. Kiểm tra bản ghi DNS và cài đặt tên miền của host. Xem cách kết nối tên miền riêng.

Làm cho trang 404 thật sự hữu ích

Một số lỗi 404 là đúng: ai đó gõ sai URL. Hãy làm cho trang đó hữu ích:

  • Một thông báo ngắn và liên kết đến trang chủ cùng các phần chính
  • Một ô tìm kiếm, nếu site có tìm kiếm
  • Cùng header và điều hướng như phần còn lại của site

Khi cấu hình cho phép, hãy trả về mã trạng thái 404 cho các trang không tồn tại. Một thông báo "không tìm thấy" trả về với trạng thái 200 chính là cái công cụ tìm kiếm gọi là soft 404, nó có thể làm lãng phí thời gian thu thập dữ liệu và gây nhầm lẫn khi lập chỉ mục.

Lỗi thường gặp

  • Chỉ kiểm tra bằng cách bấm. Luôn kiểm tra bằng cách dán URL sâu vào một tab mới rồi tải lại.
  • Fallback bắt mọi thứ. Tài nguyên và route API trả về index.html, gây trang trắng và các lỗi API khó hiểu.
  • Chữ hoa chữ thường không khớp chỉ lỗi trên máy chủ.
  • Deploy thư mục mã nguồn thay vì kết quả build.
  • Tái cấu trúc URL mà không có chuyển hướng. Mỗi liên kết cũ thành 404.

404 trong Mythex

Trên Mythex, bạn publish từ không gian làm việc, và front end tĩnh được deploy như site tĩnh. Nếu một trang đã publish bị 404, hãy đưa cho agent URL chính xác, cho biết lỗi xảy ra khi tải lại hay khi bấm, và tab Network hiển thị gì, rồi yêu cầu nó kiểm tra định tuyến. Publish lại sau khi sửa, vì app đang hoạt động là một bản chụp cho đến khi bạn publish lại. Nếu bạn vừa thay đổi dự án mà site trực tiếp vẫn cũ, hãy publish lại và tải lại bằng hard refresh. Dùng Fix with AI trong hộp thoại publish nếu build thất bại. Xem Cách publish và Xử lý sự cố khi publish trong tài liệu, và hướng dẫn của chúng tôi về gỡ lỗi app do AI xây dựng.

Danh sách kiểm tra 404

  • Đã ghi lại chính xác URL nào bị 404 và xảy ra khi bấm, khi tải lại, hay cả hai
  • Fallback SPA phục vụ index.html cho các route của app, với trạng thái 200
  • Fallback loại trừ các file thật và /api/*
  • Router có route "không tìm thấy" bắt tất cả
  • Thư mục kết quả build là thứ được publish, và build đã thành công
  • Base path khớp với nơi app được phục vụ
  • Chữ hoa chữ thường của tên file khớp với mọi tham chiếu
  • Đường dẫn tài nguyên bắt đầu bằng /
  • Kiểu dấu gạch chéo cuối nhất quán
  • Các route API đã được deploy và định tuyến trên production
  • Chuyển hướng 301 cho các URL cũ
  • Đã kiểm tra các liên kết sâu bằng cách dán vào tab mới

Câu hỏi thường gặp

Vì sao tôi bị 404 khi tải lại trang trong app React?

Trong một single-page app, các route như /dashboard chỉ tồn tại trong JavaScript. Bấm vào liên kết vẫn chạy vì router xử lý trong trình duyệt, nhưng khi tải lại, máy chủ được yêu cầu một file /dashboard không tồn tại. Cách sửa là một quy tắc fallback phục vụ index.html cho các route của app.

Làm sao thêm fallback SPA trên Netlify, Vercel hoặc Nginx?

Trên Netlify, thêm file _redirects với dòng /* /index.html 200. Trên Vercel, thêm rewrite trong vercel.json để chuyển mọi đường dẫn về /index.html. Trên Nginx, dùng try_files $uri $uri/ /index.html; trong khối location. Hãy kiểm tra tài liệu của host vì quy tắc có thể thay đổi.

Vì sao hình ảnh hoặc file của tôi bị 404 sau khi deploy?

Thường là file không nằm trong kết quả build, chữ hoa chữ thường trong đường dẫn không khớp (máy chủ thường phân biệt hoa thường trong khi máy tính của bạn thì không), hoặc đường dẫn là tương đối trong khi nó nên bắt đầu bằng dấu gạch chéo.

Trang không tồn tại có nên trả về mã trạng thái 404 thật không?

Có. Hiển thị một trang không tìm thấy hữu ích, nhưng với mã trạng thái 404 khi cấu hình cho phép. Công cụ tìm kiếm coi thông báo "không tìm thấy" trả về với trạng thái 200 là soft 404, nó làm lãng phí thời gian thu thập dữ liệu và có thể gây nhầm lẫn khi lập chỉ mục.

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 Українська اردو 简体中文 繁體中文(香港) 繁體中文(台灣)