Skip to content

Commit 1368440

Browse files
committed
fix: add redirect to raw files as well
1 parent d40fe4c commit 1368440

4 files changed

Lines changed: 39 additions & 29 deletions

File tree

app/layouts/docs.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ let observer: IntersectionObserver | undefined
66
onMounted(() => {
77
// make sure Nuxt finished hydration before observing the navigation
88
onNuxtReady(() => {
9-
console.log('on nuxt ready')
109
observer = observeNavigation(navigationRef)
1110
watch(sidebar, () => {
1211
nextTick(() => {

app/utils/navigation.ts

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ function prefetchPath(path?: string) {
99
}
1010
nuxtApp = nuxtApp ?? useNuxtApp()
1111
prefetchedPaths.add(path)
12-
console.log('prefetch', path)
1312
nuxtApp.hooks.callHook('link:prefetch', path)
1413
}
1514

@@ -57,33 +56,8 @@ function walk(items: NavigationItem[], path: string): boolean {
5756
return false
5857
}
5958

60-
/**
61-
* First leaf page under the navigation node at `path`, if `path` is a section (directory) node.
62-
* Returns `undefined` when the path isn't in the tree or already is a leaf — used to redirect
63-
* directory URLs like `/getting-started` to their first page.
64-
*/
65-
export function findFirstLeaf(
66-
navigation: NavigationItem[] | undefined | null,
67-
path: string | undefined
68-
): string | undefined {
69-
if (!navigation?.length || !path) return undefined
70-
const visit = (items: NavigationItem[]): string | undefined => {
71-
for (const item of items) {
72-
if (item.path === path) {
73-
let current = item
74-
while (current.children?.length) current = current.children[0]!
75-
// Guard: a directory `index.md` is emitted as its own first child — no redirect to self.
76-
return current.path !== path ? current.path : undefined
77-
}
78-
if (item.children?.length) {
79-
const found = visit(item.children)
80-
if (found) return found
81-
}
82-
}
83-
return undefined
84-
}
85-
return visit(navigation)
86-
}
59+
// Shared with the server-side `/raw/**` mirror (server/routes/raw/[...slug].md.get.ts).
60+
export { findFirstLeaf } from '../../utils/first-leaf'
8761

8862
export interface BreadcrumbItem {
8963
title: string

server/routes/raw/[...slug].md.get.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { findFirstLeaf } from '../../../utils/first-leaf'
2+
13
export default defineEventHandler(async (event) => {
24
const slug = getRouterParams(event)['slug.md']
35
if (!slug?.endsWith('.md')) {
@@ -9,6 +11,12 @@ export default defineEventHandler(async (event) => {
911
const path = pagePathFromRawSlug(slug)
1012
const markdown = await renderPageMarkdown(content, path)
1113
if (!markdown) {
14+
// A directory without an index page (e.g. /raw/getting-started.md) redirects to the
15+
// mirror of its first navigation page — same behaviour as the HTML pages.
16+
const firstLeaf = findFirstLeaf(await content.navigation(), path)
17+
if (firstLeaf) {
18+
return sendRedirect(event, `/raw${firstLeaf}.md`, 302)
19+
}
1220
return notFoundMarkdown(event, path)
1321
}
1422

utils/first-leaf.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { NavigationItem } from 'comark-content'
2+
3+
/**
4+
* First leaf page under the navigation node at `path`, if `path` is a section (directory) node.
5+
* Returns `undefined` when the path isn't in the tree or already is a leaf — used to redirect
6+
* directory URLs like `/getting-started` (and their `/raw/**.md` mirrors) to their first page.
7+
*/
8+
export function findFirstLeaf(
9+
navigation: NavigationItem[] | undefined | null,
10+
path: string | undefined
11+
): string | undefined {
12+
if (!navigation?.length || !path) return undefined
13+
const visit = (items: NavigationItem[]): string | undefined => {
14+
for (const item of items) {
15+
if (item.path === path) {
16+
let current = item
17+
while (current.children?.length) current = current.children[0]!
18+
// Guard: a directory `index.md` is emitted as its own first child — no redirect to self.
19+
return current.path !== path ? current.path : undefined
20+
}
21+
if (item.children?.length) {
22+
const found = visit(item.children)
23+
if (found) return found
24+
}
25+
}
26+
return undefined
27+
}
28+
return visit(navigation)
29+
}

0 commit comments

Comments
 (0)