Migrate an existing site
The DreamLake docs sites started life as copies of one template — each
carrying its own components/, lib/, and renderer. Migrating one to
@dreamlake/dockit means deleting the vendored shell and keeping only
what is genuinely site-owned: pages, branding, and deploy config.
This playbook comes from a real migration — lakeshore-workspace PR #36, which removed 5,910 lines and added 119, with the prerendered HTML byte-identical to the pre-migration baseline (modulo hashed asset filenames). Your site should land in the same shape.
Prerequisites
- Read the Quickstart first — migration is "make the site look like that," and every target file is shown there.
vike >= 0.4.260. Dockit nests Vike's plugin inside thedockit()plugin array, and earlier versions'vike prerenderCLI cannot see a nested plugin (verified: 0.4.259 fails, 0.4.260 passes). Bump the range as part of the migration.- A green pre-migration build. Record the baseline numbers — prerendered page count and pagefind's page/word counts — so you can prove parity afterwards.
What to delete
Everything that was extracted into the library. In lakeshore's case this was 5,371 lines across 24 files:
components/— the entire vendored shell (Sidebar, Topbar, TOC, TabStrip, SearchPalette, CodeBlock, Callout, Preview, StatusTable, theming, …)lib/— navigation, tabs, search-index, pagefind-search, and the hooksrenderer/Layout.tsx- The bulk of
styles/app.css— theme tokens, dark-mode overrides, and component styles all live in the library's stylesheet now
What stays, because it is site-owned: pages/**, public/**,
scripts/gen-llms.mjs, versions.lock.json, netlify.toml, and any
version/release scripts.
Old → new mapping
| Old (vendored template) | New (dockit) |
|---|---|
site.config.ts (plain config object) | A single initDocs() call. Branding fields carry over unchanged (brand, subtitle, repoUrl, docsRepoUrl, docsBranch, breadcrumbRoot, url, skill, summary); add versionChips, gitHash, and docsPagesPath. |
lib/tabs.ts (TABS array) | The tabs option of initDocs — same TabDef shape, moved verbatim. |
lib/navigation.ts (SECTION_ORDER) | The sectionOrder option of initDocs, moved verbatim. |
vite.config.ts hand-rolled plugin stack (MDX + remark/rehype + shiki + Tailwind + React + Vike) | plugins: [...dockit()]. Keep any site-specific prelude — version reads, define blocks, server options — around it, verbatim. |
renderer/+config.ts, +onRenderHtml.tsx, +onRenderClient.tsx (real implementations) | Three thin re-export wrappers over @dreamlake/dockit/vike, /server, and /client. site.config must be the first import so initDocs runs before render. |
styles/app.css (hundreds of lines of tokens and overrides) | Three lines: @import "tailwindcss", @import "@dreamlake/dockit/styles.css", plus @source lines for ../pages and ../renderer. |
The wrappers, config call, and CSS are spelled out file by file in the
Quickstart; the full initDocs surface is
in the config reference.
package.json changes
Add:
Bump:
Remove the docs-stack deps the dockit() factory now provides:
@mdx-js/rollup, the remark/rehype plugins, shiki,
@tailwindcss/vite, and @vitejs/plugin-react. Keep the peers
(react, react-dom, tailwindcss, vike, vike-react, @mdx-js/react) and the
tooling (vite, typescript, pagefind) — see
Quickstart prerequisites for the exact split. The
build script is unchanged:
vite build && vike prerender && node scripts/gen-llms.mjs && pagefind --site dist/client.
A directory-form file: override of the package falsely crashes
vike prerender with a duplicate-vike-plugin assert — the symlinked
directory makes Vike's plugin register twice. It is an artifact of the
override, not a bug in your migration. Run npm pack in the library
and point the override at the tarball instead; that matches real npm
resolution and prerenders cleanly. Revert the override before
committing.
Verification checklist
Run the same gauntlet lakeshore's migration did, and compare against your pre-migration baseline:
- Full build —
vite build && vike prerender && node scripts/gen-llms.mjs && pagefind --site dist/clientcompletes green. - Prerender count parity — the same number of HTML documents as before (lakeshore: 101), and identical pagefind page/word counts. For full confidence, diff the prerendered HTML against the baseline: it should be byte-identical modulo hashed asset filenames.
check:llms— passes with the committedskills/<name>/unchanged (pages untouched means generated surfaces untouched).tsc --noEmit— clean. Deleted shell code means deleted types; any residual import ofcomponents/orlib/surfaces here.- Dev smoke —
vitedev server: load/plus one page per tab and confirm titles, sidebar, and search all behave.
Check version-chip scope during migration: tabs inherit the global chips by default, and TabDef.versionChips can replace or hide them per tab. See scoping chips per tab.
Ship it
Once green, deploy as usual — Netlify needs no changes beyond the
lockfile: run pnpm install at the workspace root after the
dependency edits, and commit both package.json and pnpm-lock.yaml
together.
If your site predates versioned deploys (or its release scripts have
drifted), the package ships current copies at
node_modules/@dreamlake/dockit/templates/ — see
Releases & versioning.
Orient your agents
Use the shared agent setup fragment after the migration. It records the page layout and regeneration checks without duplicating renderer implementation details.