Skip to main content

Inside vdoc

vdoc frames each published site inside its own application. The header, version picker and footer links belong to vdoc; everything inside the frame is yours.

The agreement between the two is written down as the frame contract, which numbers its requirements R1 to R10. This page is what those mean for a Docusaurus site; the theme implements all of them, so you only need this if something looks wrong, or if you are adopting the same contract in another generator.

The color mode comes from vdoc

vdoc owns the switch in its header, because that switch also themes vdoc's own chrome, something a switch inside the frame could never reach. It passes the mode in on the frame URL:

/static/projects/<project>/<version>/?vdoc-theme=dark&vdoc-inset=24

An inline script applies it before the first paint and sets data-vdoc-theme on <html> to declare that it did. vdoc reads that attribute and nothing else. Without the parameter the script does nothing at all and Docusaurus behaves exactly as it would anywhere else.

Nothing is written to browser storage. The URL carries the mode on every load, so a first visit already opens in the right mode, which a stored preference could not do.

The theme drops what vdoc already shows

Three things, all of which vdoc renders around the frame itself:

Hidden while framedBecause vdoc
The voraus wordmarkcarries it in the header directly above the navbar
The color-mode switchowns it, and it also themes vdoc's own chrome
The footerrepeats the copyright below the frame, with the imprint

Your project name and version stay in the navbar. They are the one thing vdoc's header never says.

All three are hidden by CSS keyed on data-vdoc-theme, so they are gone before the first paint. A React condition would only be decided at hydration, and each would appear and then vanish on every load.

A reader who opens the site directly, without vdoc, keeps all three.

The navbar takes its left edge from vdoc

With the wordmark hidden there is nothing left to line the project name up against, and only vdoc knows where its own header content starts. So it sends the offset (vdoc-inset=24 above) and the theme applies it as the navbar's horizontal padding (R9).

Nothing is hardcoded on this side, which matters because vdoc keeps every published version forever: a number baked into a stylesheet would strand every site published before vdoc next changed its header. An absent or malformed value leaves the theme's own layout alone.

Light mode gets a real background

Docusaurus leaves the light-mode background transparent and relies on the browser's white canvas. An embedded document has no canvas, so vdoc's dark chrome would show through and the page would render dark text on black. The theme paints an opaque surface instead.

Seeing it locally

Because the framed state comes from the parameter and not from being in a frame, you can see exactly what a reader inside vdoc sees:

http://localhost:3000/static/projects/voraus-example/1.2.0/?vdoc-theme=dark

The wordmark and the color-mode toggle disappear and the page is in vdoc's dark mode.

The query has to come before the fragment. Everything after a # is the fragment, so the first of these does nothing:

.../inside-vdoc#some-heading?vdoc-theme=dark <- ignored
.../inside-vdoc?vdoc-theme=dark#some-heading <- works

Easy to get wrong, because copying an anchor link from a heading gives you the # first.