diff --git a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs
index 8edac3cace..be7de1bbbe 100644
--- a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs
+++ b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs
@@ -39,7 +39,8 @@ impl HtmlHandlebars {
let path = ch.path.as_ref().unwrap();
// "print.html" is used for the print page.
- if path == Path::new("print.md") {
+ // "toc.html" is used for the no-JS table of contents fallback.
+ if path == Path::new("print.md") || path == Path::new("toc.md") {
bail!("{} is reserved for internal use", path.display());
};
diff --git a/guide/src/format/summary.md b/guide/src/format/summary.md
index 85d3b7406c..0a0e2ff570 100644
--- a/guide/src/format/summary.md
+++ b/guide/src/format/summary.md
@@ -90,6 +90,18 @@ to be ignored at best, or may cause an error when attempting to build the book.
```
+### Reserved file names
+
+A few source file names are reserved for files mdBook generates itself, and
+cannot be used as chapter paths:
+
+- `print.md`: the printable single-page view (`print.html`) is generated from
+ the book's chapters. Referencing `print.md` from `SUMMARY.md` causes the
+ build to fail with `print.md is reserved for internal use`.
+- `toc.md`: the no-JavaScript table of contents (`toc.html`) is generated from
+ `SUMMARY.md`. Referencing `toc.md` from `SUMMARY.md` causes the build to
+ fail with `toc.md is reserved for internal use`.
+
### Example
Below is the markdown source for the `SUMMARY.md` for this guide, with the resulting table
diff --git a/guide/src/guide/creating.md b/guide/src/guide/creating.md
index 613114c82b..b58569f780 100644
--- a/guide/src/guide/creating.md
+++ b/guide/src/guide/creating.md
@@ -93,6 +93,22 @@ Check out the [Markdown chapter](../format/markdown.md) for more information on
All other files in the `src` directory will be included in the output.
So if you have images or other static files, just include them somewhere in the `src` directory.
+### Reserved file names
+
+A few file names in the `src` directory are reserved by mdBook for files it
+generates itself. You cannot use them as the source path for a chapter in
+`SUMMARY.md`, and the HTML renderer will refuse to build the book if it finds
+them.
+
+- `print.md` / `print.html`: `print.html` is the single-page printable view of
+ the whole book, used when a reader clicks the printer icon. It is generated
+ from the book's chapters, so `src/print.md` is rejected with an error.
+ See [`[output.html.print]`](../format/configuration/renderers.md#outputhtmlprint)
+ for the related configuration.
+- `toc.md` / `toc.html`: `toc.html` is the no-JavaScript table of contents
+ fallback used by readers and crawlers that don't run JavaScript. It is
+ generated from `SUMMARY.md`, so `src/toc.md` is rejected with an error.
+
## Publishing a book
Once you've written your book, you may want to host it somewhere for others to view.
diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs
index 889a9e65ea..4c894f528e 100644
--- a/tests/testsuite/build.rs
+++ b/tests/testsuite/build.rs
@@ -55,6 +55,20 @@ ERROR Rendering failed
});
}
+// Checks that it fails if the summary references the reserved `toc.md` name.
+#[test]
+fn no_reserved_filename_toc() {
+ BookTest::from_dir("build/no_reserved_filename_toc").run("build", |cmd| {
+ cmd.expect_failure().expect_stderr(str![[r#"
+ INFO Book building has started
+ INFO Running the html backend
+ERROR Rendering failed
+[TAB]Caused by: toc.md is reserved for internal use
+
+"#]]);
+ });
+}
+
// Build without book.toml should be OK.
#[test]
fn book_toml_isnt_required() {
diff --git a/tests/testsuite/build/no_reserved_filename_toc/book.toml b/tests/testsuite/build/no_reserved_filename_toc/book.toml
new file mode 100644
index 0000000000..bb3f49ce0a
--- /dev/null
+++ b/tests/testsuite/build/no_reserved_filename_toc/book.toml
@@ -0,0 +1,2 @@
+[book]
+title = "no_reserved_filename_toc"
diff --git a/tests/testsuite/build/no_reserved_filename_toc/src/SUMMARY.md b/tests/testsuite/build/no_reserved_filename_toc/src/SUMMARY.md
new file mode 100644
index 0000000000..0f3901213b
--- /dev/null
+++ b/tests/testsuite/build/no_reserved_filename_toc/src/SUMMARY.md
@@ -0,0 +1,3 @@
+# Summary
+
+- [TOC](toc.md)
diff --git a/tests/testsuite/build/no_reserved_filename_toc/src/toc.md b/tests/testsuite/build/no_reserved_filename_toc/src/toc.md
new file mode 100644
index 0000000000..8b0718a8d3
--- /dev/null
+++ b/tests/testsuite/build/no_reserved_filename_toc/src/toc.md
@@ -0,0 +1 @@
+# TOC