# 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](https://github.com/dreamlake-ai/lakeshore-workspace/pull/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](/get-started/quickstart.md) 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 the
  `dockit()` plugin array, and earlier versions' `vike prerender` CLI
  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
  hooks
- `renderer/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](/get-started/quickstart.md); the full `initDocs` surface is
in the [config reference](/reference/config.md).

## package.json changes

Add:

```json
"@dreamlake/dockit": "^0.1.0"
```

Bump:

```json
"vike": "^0.4.260"
```

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](/get-started/quickstart.md#install) for the exact split. The
`build` script is unchanged:
`vite build && vike prerender && node scripts/gen-llms.mjs && pagefind --site dist/client`.

> **Warning:** 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:

1. **Full build** — `vite build && vike prerender && node
   scripts/gen-llms.mjs && pagefind --site dist/client` completes
   green.
2. **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.
3. **`check:llms`** — passes with the committed `skills/<name>/`
   unchanged (pages untouched means generated surfaces untouched).
4. **`tsc --noEmit`** — clean. Deleted shell code means deleted types;
   any residual import of `components/` or `lib/` surfaces here.
5. **Dev smoke** — `vite` dev 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](/guides/site-config.md#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](/guides/releases.md).

## Orient your agents

Use the shared [agent setup fragment](/guides/llms.md#orient-your-agents) after the migration. It records the page layout and regeneration checks without duplicating renderer implementation details.
