A sandbox site is a complete Leed site that lives only on your machine. It builds and previews like any other site, with no Leed account, no sign-in and no CMS behind it, so you can design and fill a whole site before you sign up. When you are happy with it and have an account, the Leed plugin for Claude moves it into your real Leed site, creating every CMS record it needs along the way.
One command makes it:
leed site init --sandbox my-site
cd my-site
leed site build --serveThe site is now at http://localhost:8080, rebuilding as you edit, exactly as described in Local Development.
What --sandbox writes
leed site init --sandbox [dir] creates the site in dir, or in ./leed-sandbox when you give the flag on its own. The folder must not exist yet, or must be empty: init never writes over your files, and refuses any other target with invalid_arguments.
Into that folder it copies a fixed set of files that ships with the CLI:
identity.jsonholding{ "companyId": "non-cms-company", "environment": "dev" }. That company id can never be a real one, and it is how every later command knows it is in a sandbox.- The data a build needs, under
src/_data/(page types, menus, labels, users, forms, search indexes, autolinks and calls to action) plussrc/src.11tydata.json. In a real site the CMS publishes these files; here they are written once, by hand or by Claude. - A starting set of templates and styles:
src/index.hbs,src/404.hbs, layouts, partials andtailwind/. src/static/images/tmp/, where images wait until the move uploads them. The sandbox’s.gitignoreexcludes it.
It then installs Font Awesome Free into the site, the only download a sandbox init makes. Offline, the sandbox is still written and the result carries a warning: run leed site init --font-awesome inside the sandbox later to install the icons.
Nothing else a real leed site init does happens here. There is no sign-in, no clone, no git repository and no git hooks. The sandbox is recorded in the site registry, ~/.config/leed/sites.json, so leed site list shows it with sandbox: true and you can name it later by its folder.
Placeholder ids
Every record in a sandbox is named with a readable placeholder instead of a CMS id: ph-<kind>-<n>, such as ph-pt-2 for a page type or ph-page-10 for a page. Pages, menus and templates refer to each other through those placeholders exactly as a real site uses ids, so a pageid:ph-page-3 link and a menu item pointing at it both resolve in the preview.
| Kind | Placeholder |
|---|---|
| Page type | ph-pt-<n> |
| Page | ph-page-<n> |
| Label | ph-label-<n> |
| Author | ph-author-<n> |
| Menu, menu item | ph-menu-<n>, ph-menuitem-<n> |
| Form | ph-form-<n> |
| Search index | ph-index-<n> |
Images are not placeholders: they are files in src/static/images/tmp/, referred to as /static/images/tmp/<file>. The move uploads each one to the asset manager and rewrites every reference.
What works in a sandbox
Everything that works on the folder alone keeps working. Everything that needs the CMS refuses, before it signs in or touches the network.
| Works | Refuses |
|---|---|
leed site build, including --serve | leed site validate, commit and push |
leed site eject, leed site vscode, leed site list | leed settings …, every subcommand |
leed import markdown, html, openapi and clean, which stage content for the preview | leed import apply and leed import status |
leed auth login, logout and status, and leed setup | leed page … and leed asset … |
leed mcp add --docs and leed mcp docs | leed mcp add --cms |
leed schema, leed self-update and shell completion | leed deployments …, leed contacts … and leed feedback blocked |
A refused command fails with the code sandbox_site and exit status 3, a precondition the move satisfies:
This is a local sandbox site (non-cms-company), and leed site push needs the Leed CMS.
Move the site into Leed first with /leed:site-sandbox-move in Claude.No login or retry helps; the site has to be moved first. Inside a sandbox the CLI also skips its daily automatic update check, so the CLI never replaces itself while you work in one. The full code table is in CLI Troubleshooting and Exit Codes.
Plan features are all on
A sandbox has no plan, so nothing is gated locally: its template data names the Enterprise plan, which lets the preview render every template and style the CMS offers, paid ones included, so you can see how far your site could go. Your company’s real plan applies from the moment the site is moved. leed site eject --json reports tier: null in a sandbox, so a step that checks the plan, such as /leed:create recommendations or /leed:create cta, which need the Growth plan, stops there with the plan message.
Building a sandbox with Claude
The sandbox is designed for the Leed plugin for Claude, whose skills know how to write the records a sandbox holds. Ask Claude to start a sandbox site, or create one yourself and open Claude Code in it. Then:
/leed:create blogand/leed:create documentationhave a sandbox path. Instead of calling the CMS they write the page type intosrc/_data/pageTypeList.json, a documentation set’s left menu and search index beside it, and the starter templates, each record with a fresh placeholder, and finish with a preview rather than a publish.site-design-importturns a Claude Design handoff into the sandbox’s theme, layouts and menus, keeping its images as local files.site-migratestages a migration from Docusaurus, MkDocs, GitBook, Mintlify, ReadMe, VitePress or Nextra in the sandbox, with pages as Leed Markdown underleed-import/.
None of them publishes: every one ends with leed site build --serve and names the move. What each skill does is in The Leed Plugin for Claude: Skills.
Moving the sandbox into Leed
When you have a Leed account, two things come first: sign in, and set up your real site with /leed:setup, which leaves a raw-content checkout on your machine. See Get Started with the Leed Plugin for Claude. Then run /leed:site-sandbox-move in Claude Code. There is no CLI command for the move: it is a skill, with scripts that inventory, plan, rewrite, check and copy the sandbox, and it drives the ordinary leed settings, leed page and leed asset commands from inside your real checkout.
The move follows the CMS’s own dependency order, so each record exists before anything that refers to it:
flowchart TD
Plan["Inventory and plan every placeholder"] --> Layouts["Copy and push the layouts<br/>(a page type needs its layout on staging)"]
Layouts --> Types["Page types, labels, authors"]
Types --> Pages["A placeholder page for each Markdown page"]
Pages --> Images["Images to the asset manager"]
Images --> Menus["Menus and their items, forms,<br/>search indexes, calls to action, autolinks"]
Menus --> Check{"Any ph- id or staged image left?"}
Check -->|yes| Rewrite["Map it and rewrite again"]
Rewrite --> Check
Check -->|no| Copy["Copy templates, tailwind/ and src/static/<br/>into the real checkout"]
Copy --> Content["Fill the pages and import leed-import/"]
Content --> Final["Final check, build, publish the new settings,<br/>validate, commit, push, check staging"]
After each step the move writes the real ids back into the sandbox in place of the placeholders, so the next step already carries them. A few things are worth knowing before you start:
- Nothing is created twice. Every Leed site already has a root page type, a home page and a Header and Footer menu; the move maps the sandbox’s to those. Creating a documentation page type creates its left menu and search index, so those are mapped, not created.
- Authors must be real users. The CLI cannot create users, so each sandbox author is matched to a team member by email. When nobody matches, Claude asks whether to invite them in the CMS first or credit someone else.
- Templates above your plan cannot come across. The move checks your plan before copying, and tells you about any template the sandbox used that your plan does not include.
- It fails loudly. The copy into your checkout runs only once no placeholder and no staged-image reference is left, and the final check fails if one reaches the real site or a created page was never filled.
- It resumes. The move keeps its id map and a list of filled pages outside both folders, so a stopped move picks up from the first record it has not made.
The sandbox stays where it was, with real ids now in place of its placeholders, and is no longer needed; deleting it is up to you. The pages it filled are ready for review in the editor, like any page Claude writes.