Headers not showing in sidebar when extending default theme in VuePress 2 #1668
Unanswered
nancy1234567890
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I’m creating a custom VuePress 2 theme that extends the default theme.
Everything works (sidebar, navbar, search, etc.), but page headers (H2/H3) never appear as children in the sidebar.
When I log page.value.headers, it’s always undefined, and my extendsPage() hook never runs.
So it looks like my page-extension logic isn’t being called.
Environment
VuePress v2.x
Node v18.x
Using extends: defaultTheme(options)
Directory structure:
docs/
├─ .vuepress/
│ ├─ config.js
│ └─ theme/
│ ├─ index.js
│ ├─ client.js
│ └─ layouts/
│ └─ Layout.vue
vuepress/config.js
import { defineUserConfig } from 'vuepress'
import theme from './theme'
export default defineUserConfig({
lang: 'en-US',
title: 'Sample Docs',
theme,
markdown: { headers: { level: [2, 3] } },
})
.vuepress/theme/index.js
import { path } from '@vuepress/utils'
import { defaultTheme } from '@vuepress/theme-default'
import { searchPlugin } from '@vuepress/plugin-search'
import { themeDataPlugin } from '@vuepress/plugin-theme-data'
export default (options) => ({
extends: defaultTheme(options),
name: 'custom-theme',
clientConfigFile: path.resolve(__dirname, './client.js'),
plugins: [
searchPlugin({
locales: { '/': { placeholder: 'Search documentation' } },
}),
themeDataPlugin({ themeData: options }),
],
extendsPage(page) {
if (page.headers?.length) return
const matches = [
...page.contentRendered.matchAll(/<h([23]) id="([^"]+)".?>(.?)</h[23]>/g),
]
if (matches.length) {
page.headers = matches.map(([_, level, slug, title]) => ({
level: Number(level),
slug,
title: title.replace(/</?[^>]+(>|$)/g, ''),
}))
}
console.log('Extracted headers for', page.path, page.headers)
},
})
What I See
Build succeeds.
Console does not show Extracted... Log at all
Opening any other page (for example /guide/) prints nothing.
page.value.headers is undefined inside Layout.vue and sidebar components.
Sidebar only shows children if defined in config, no headers as children
What I Expect
The extendsPage() hook should run for every Markdown page.
page.headers should contain the page’s H2/H3 headings, for example:
[
{ level: 2, slug: 'overview', title: 'Overview' },
{ level: 2, slug: 'setup', title: 'Setup' }
]
Those headers should appear as collapsible children in the sidebar.
What I Tried
Verified that Markdown files contain ## headings.
Added markdown.headers.level = [2, 3] in config.
Tried both styles:
const base = defaultTheme(options)
base.extendsPage = (...) => {}
return base
and
export default (options) => ({ extends: defaultTheme(options), extendsPage(page) {...} })
Still only see Extracted headers for /404.html [].
Is the extendsPage() hook expected to run when using
extends: defaultTheme(options) in a custom theme?
If yes, what’s the correct way to make sure it runs for all Markdown pages
so that page.headers is populated and usable in the sidebar?
Beta Was this translation helpful? Give feedback.
All reactions