Skip to content

Commit bdba5c5

Browse files
committed
fix(prerender): serve actual 404 page for unmatched routes
Add a /not-found route (pre-rendered to dist/not-found/index.html) and copy it as dist/404.html instead of the landing page index.html. Exclude /not-found from the sitemap. Falls back to index.html if the not-found render fails for any reason.
1 parent 94c6bb8 commit bdba5c5

2 files changed

Lines changed: 17 additions & 6 deletions

File tree

build.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ fn main() {
5353
let theme = &ts.themes["base16-ocean.dark"];
5454

5555
let mut pages: Vec<DocPage> = Vec::new();
56-
let mut routes = vec!["/".to_string(), "/docs".to_string()];
56+
let mut routes = vec![
57+
"/".to_string(),
58+
"/docs".to_string(),
59+
"/not-found".to_string(),
60+
];
5761

5862
for entry in WalkDir::new(content_dir)
5963
.into_iter()

src/bin/prerender.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,17 @@ fn main() {
116116
println!(" search_index.json -> dist/search_index.json");
117117
}
118118

119-
// Generate 404.html from index
120-
let index_path = dist_dir.join("index.html");
121-
if index_path.exists() {
122-
fs::copy(&index_path, dist_dir.join("404.html")).ok();
119+
// Generate 404.html from the pre-rendered /not-found route
120+
let not_found_path = dist_dir.join("not-found").join("index.html");
121+
let fallback_path = dist_dir.join("index.html");
122+
let source_404 = if not_found_path.exists() {
123+
&not_found_path
124+
} else {
125+
&fallback_path
126+
};
127+
if source_404.exists() {
128+
fs::copy(source_404, dist_dir.join("404.html")).ok();
129+
println!(" {} -> dist/404.html", source_404.display());
123130
}
124131

125132
// Generate robots.txt
@@ -133,7 +140,7 @@ fn main() {
133140
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
134141
<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n",
135142
);
136-
for route in &routes {
143+
for route in routes.iter().filter(|r| **r != "/not-found") {
137144
let priority = if *route == "/" { "1.0" } else { "0.8" };
138145
let loc = if *route == "/" {
139146
base_url.clone()

0 commit comments

Comments
 (0)