Skip to content

Commit 052835b

Browse files
authored
Redirect /subdir to /subdir/ when the page is given by docs/subdir/index.md (#274)
* Redirect /subdir to /subdir/ when the page is given by docs/subdir/index.md. Otherwise links seen in preview under /subdir can look correct, but will fail in the build. To test, run: > yarn dev --root test/input/build/multi/ and open http://127.0.0.1:3000/subsection * more precise redirection: Given a /dir/index(.html) path, we redirect the browser to /dir/ if there is a dir/index.md file, otherwise to /dir. This accomodates /javascript in the documentation as well as test/input/build/multi/subsection/ * remove redundant check
1 parent d88ba1b commit 052835b

3 files changed

Lines changed: 23 additions & 6 deletions

File tree

src/preview.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,31 @@ export class PreviewServer {
123123

124124
// If this path is for /index, redirect to the parent directory for a
125125
// tidy path. (This must be done before implicitly adding /index below!)
126+
// Respect precedence of dir/index.md over dir.md in choosing between
127+
// dir/ and dir!
126128
if (basename(path, ".html") === "index") {
127-
res.writeHead(302, {Location: dirname(pathname) + url.search});
128-
res.end();
129-
return;
129+
try {
130+
await stat(join(dirname(path), "index.md"));
131+
res.writeHead(302, {Location: dirname(pathname) + "/" + url.search});
132+
res.end();
133+
return;
134+
} catch (error) {
135+
if (!isEnoent(error)) throw error;
136+
res.writeHead(302, {Location: dirname(pathname) + url.search});
137+
res.end();
138+
return;
139+
}
130140
}
131141

132142
// If this path resolves to a directory, then add an implicit /index to
133143
// the end of the path, assuming that the corresponding index.md exists.
134144
try {
135-
if ((await stat(path)).isDirectory() && (await stat(join(path, "index") + ".md")).isFile()) {
136-
await access(join(path, "index") + ".md", constants.R_OK);
145+
if ((await stat(path)).isDirectory() && (await stat(join(path, "index.md"))).isFile()) {
146+
if (!pathname.endsWith("/")) {
147+
res.writeHead(302, {Location: pathname + "/" + url.search});
148+
res.end();
149+
return;
150+
}
137151
pathname = join(pathname, "index");
138152
path = join(path, "index");
139153
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# Sub-Section
22

3-
This is a sub-section of the multi-section page.
3+
This is a sub-section of the multi-section page.
4+
5+
We can link to [this sub-section](./) and to [the parent section](../).

test/output/build/multi/subsection/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<main id="observablehq-main" class="observablehq">
3434
<h1 id="sub-section" tabindex="-1"><a class="observablehq-header-anchor" href="#sub-section">Sub-Section</a></h1>
3535
<p>This is a sub-section of the multi-section page.</p>
36+
<p>We can link to <a href="./">this sub-section</a> and to <a href="../">the parent section</a>.</p>
3637
</main>
3738
<footer id="observablehq-footer">
3839
<nav><a rel="prev" href="../"><span>Home</span></a></nav>

0 commit comments

Comments
 (0)