Rabbithole Documentation — github.com/ajbt200128/rabbithole — live at isarabbithole.com
Rabbithole generates each page in complete isolation: a single prompt is the only input the LLM receives. There is no shared memory, no session state, no inherited context between pages. This makes prompt quality the single most important factor in whether your site feels coherent and intentional or like a random collection of unrelated pages. This guide covers everything you need to write prompts that produce consistent, high-quality results across deep link chains.
The seed prompt is the description of your homepage — the founding document of the entire site. Every other page eventually traces its lineage back to context you establish here. Treat it as a complete creative brief: if you would need to tell a designer about it, put it in the seed prompt.
Documentation homepage for Rabbithole — an open-source Rust tool
(github.com/ajbt200128/rabbithole, live at isarabbithole.com) that
dynamically generates entire websites on the fly using LLMs (Anthropic
Claude). <-- subject matter
DESIGN: Plain minimal HTML like gcc.gnu.org or Craigslist. White
background (#ffffff), system fonts (Arial/Helvetica body, Times New
Roman headings), no gradients, no shadows, no rounded corners. <-- visual design
Blue links (#0000cc), visited purple (#551a8b). <-- link colors
Pre/code with #f4f4f4 bg and 1px solid #ccc. Dense layout. No JS.
NAV (pipe-separated, top of page): <-- nav structure
Home | Getting Started | Architecture | Configuration |
Web Tools | Deployment | Examples | About
(paths: /index.html, /docs/getting-started.html, ...)
TONE: Technical, terse, direct documentation prose. <-- tone
CONTENT: Hero intro explaining what Rabbithole does; feature list;
quick-start snippet; links to all doc sections. <-- page content
Note how design, nav, tone, and content are all separable concerns, each addressed explicitly. The more precisely you specify each dimension, the less the model has to guess — and guessing is where inconsistency enters.
When Rabbithole generates a linked page, it invokes the LLM in a fresh context. The only input is the prompt string you wrote when generating the parent page. There is no:
This is not a bug — it is a deliberate architectural choice that enables caching, parallelism, and stateless deployment. But it means every prompt must carry the full blueprint.
"About page for the Rabbithole project.""About page for Rabbithole — open-source Rust LLM site generator
(github.com/ajbt200128/rabbithole). DESIGN: white bg #ffffff, Arial/Helvetica body, Times New Roman headings,
blue links #0000cc, visited #551a8b, no gradients, no rounded corners, pre/code #f4f4f4 bg 1px solid #ccc,
dense layout, no JS. NAV (pipe-separated): Home|Getting Started|Architecture|Configuration|Web Tools|
Deployment|Examples|About (/index.html, /docs/getting-started.html, ...). TONE: terse technical docs.
CONTENT: project history, motivation, contributors, license (MIT), links to GitHub."
The good version could stand alone as input to any LLM and produce a page visually and tonally consistent with the rest of the site, even if the model has never seen any other page.
Imagine you are handing off a one-page design brief to a contractor who will never see any other page of your site. They will produce exactly what you describe and nothing more. Everything they need must be on that sheet of paper. The same principle applies here.
The most common failure. Symptoms: linked pages use different color schemes, different font stacks, different heading hierarchy, gradients appear where none were wanted, link colors differ.
Root cause: The linked-page prompt omitted the design specification, so the model fell back to its default aesthetic (often modern Bootstrap-style with rounded corners and drop shadows).
Fix: Always copy the full design block — background, fonts, link colors, border styles, code block styles — verbatim into every linked-page prompt. Consider defining a reusable "design spec" string in your seed prompt comments and manually pasting it everywhere.
The page starts on-topic but drifts into tangential or invented content. A configuration page for a Rust CLI tool starts discussing Python config parsers. A character bio in a fantasy site contradicts lore established on the homepage.
Root cause: The prompt described the subject too vaguely ("configuration options") without grounding it in the specific project context and constraints.
Fix: Always include the project name, its actual domain (Rust, LLMs, documentation, etc.), and concrete facts (GitHub URL, actual config keys, real character names). Specificity anchors the model.
The page is technically on-topic and well-designed, but it contains nothing specific to your project. It reads like boilerplate that could describe any tool of the same type.
Root cause: Prompt said "explain how to deploy the tool" without specifying the actual deployment method (systemd, Docker, fly.io, etc.), command-line flags, config file format, or platform constraints.
Fix: Front-load concrete facts. If you want the page to mention specific flags, name them. If there's a real config file format, describe its keys. If there's a specific deployment platform, say so. The more specific facts you provide, the less the model must hallucinate.
Linked pages generate nav bars with different items, different ordering, or different paths than the rest of the site, causing broken or inconsistent navigation.
Root cause: Nav structure was not specified in the linked-page prompt, or was specified incompletely (labels but no paths, or paths but no labels).
Fix: Always include the full nav specification: every label, its separator character, and its exact absolute path. Example:
NAV (pipe-separated, top of every page):
Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About
/index.html | /docs/getting-started.html | /docs/architecture.html | /docs/configuration.html |
/docs/web-tools.html | /docs/deployment.html | /examples.html | /about.html
A generated page fails to link to subpages, or generates links with incorrect or non-canonical paths (e.g.,
getting-started instead of /docs/getting-started.html).
Fix: In your prompt, explicitly list the links the page should generate and the exact URL paths they should point to. Rabbithole will only cache and serve pages whose URLs were registered in the mappings output. A link with the wrong path will 404.
All headings render at the same size, or the page uses only <h1> for everything. Alternatively,
the page has no semantic structure at all — just a wall of text.
Fix: Specify heading hierarchy in the design spec: "h2 with bottom border, h3 bold sans-serif, h1 serif for page title only." Include an example in the prompt if needed.
Pages 1–2 look consistent. By page 4–5 (page → subpage → sub-subpage → deep link), the design has subtly shifted: slightly different padding, a color that's close but not quite right, a nav item that went missing.
Root cause: Each page author (the model) rewrote the design spec slightly when writing child prompts, introducing small mutations that compound across generations.
Fix: See Section 4 on maintaining consistency in deep chains.
Every time a page is generated, it also writes prompts for its child pages. If the model slightly paraphrases the design spec when writing those child prompts, the error compounds: grandchild pages get a paraphrase of a paraphrase, and so on. After 3–4 hops, the design can drift noticeably.
Structure your design spec so it reads like a structured data block rather than prose. Prose invites paraphrasing; structured data with explicit key-value pairs is more likely to be preserved verbatim:
DESIGN SPEC (copy verbatim into all child page prompts):
bg: #ffffff | text: #000000 | link: #0000cc | visited: #551a8b
body-font: Arial, Helvetica, sans-serif, 14px
heading-font: Times New Roman, serif
h1: 24px bold | h2: 18px bold, border-bottom: 1px solid #000
code/pre: bg #f4f4f4, border 1px solid #ccc, Courier New 13px
no gradients | no shadows | no rounded corners | no JS
layout: dense, max-width 860px, centered
The key-value format is harder to accidentally rewrite in a different way than flowing prose like "use a white background with Arial fonts and blue links."
In your seed prompt (and in every page prompt), include an instruction like:
IMPORTANT: When writing prompts for linked pages in the mappings JSON,
always include the full DESIGN SPEC and NAV SPEC blocks above, verbatim,
at the top of each child prompt. Do not paraphrase or abbreviate them.
This "meta-instruction" tells the model generating each page to preserve fidelity when it writes its children's prompts. It cannot guarantee perfect preservation, but it significantly reduces drift.
Reference canonical external anchors that uniquely identify the project and its aesthetic in the real world:
"Plain minimal HTML like gcc.gnu.org or Craigslist — not Bootstrap,
not Tailwind, not Material Design."
These reference points activate strong, specific model priors. "Like gcc.gnu.org" is harder to drift away from than "simple and minimal" because the model has seen gcc.gnu.org and knows what it looks like.
Every extra hop in a chain is another opportunity for drift. If your site has a deep hierarchy, consider whether some pages can be combined, or whether very deep pages (3+ hops from root) really need to be generated dynamically rather than linked to as static anchors or external URLs.
Don't just say what you want — say what you explicitly forbid. This is especially valuable for design:
NO gradients. NO box-shadow. NO border-radius. NO external CSS frameworks.
NO JavaScript. NO dark mode toggle. NO sticky headers. NO hero images.
Negative constraints are highly stable across paraphrasing: even if the model rewrites your design spec, "NO gradients" is hard to accidentally invert.
Longer prompts carry more context and produce more consistent, accurate results. But each prompt is passed to the LLM at generation time, and the LLM must also write child prompts of similar length. This creates a direct cost tradeoff.
| Prompt length | Cost per page | Consistency | Accuracy | Risk |
|---|---|---|---|---|
| Very short (<50 words) | Minimal | Poor | Poor | Generic, drifted pages |
| Short (50–150 words) | Low | Moderate | Moderate | Design drift after 2–3 hops |
| Medium (150–400 words) | Moderate | Good | Good | Some drift in deep chains |
| Long (400–800 words) | Higher | Very good | Very good | Context window pressure on deep chains |
| Very long (>800 words) | High | Excellent | Excellent | Model may truncate child prompts |
For most sites, 150–400 words per prompt is the practical sweet spot. This is enough to carry a full design spec, nav structure, tone descriptor, and page-specific content brief without creating runaway token cost or triggering child-prompt truncation.
The design spec and nav spec tend to be the most important content to preserve and are also among the most compressible: a key-value design block covering all critical styling can be written in under 60 words and will dominate consistency outcomes more than any other factor.
Structure prompts with a fixed "header" (design + nav — same for every page) and a variable "body" (page-specific content). This lets you optimize each section independently:
[FIXED HEADER — copy verbatim to all child prompts, ~80 words]
Site: Rabbithole docs (github.com/ajbt200128/rabbithole, isarabbithole.com)
bg #ffffff | text #000 | link #0000cc | visited #551a8b
fonts: Arial/Helvetica body 14px, Times New Roman headings
h2: 18px serif, border-bottom 1px solid #000
pre/code: bg #f4f4f4 1px solid #ccc Courier New 13px
no gradients, no shadows, no rounded corners, no JS, max-width 860px
NAV (pipe | ): Home /index.html | Getting Started /docs/getting-started.html |
Architecture /docs/architecture.html | Configuration /docs/configuration.html |
Web Tools /docs/web-tools.html | Deployment /docs/deployment.html |
Examples /examples.html | About /about.html
[VARIABLE BODY — specific to this page]
PAGE: Configuration reference. Cover: environment variables (ANTHROPIC_API_KEY,
RABBITHOLE_PORT, RABBITHOLE_CACHE_DIR), the rabbithole.toml format,
cache backend options, timeout settings, log level. Use a table for each
config key with columns: key, type, default, description.
The following templates can be copied and adapted for common page types.
[PAGE NAME] page for Rabbithole — open-source Rust LLM site generator
(github.com/ajbt200128/rabbithole, live at isarabbithole.com).
Each page generated in isolation by Anthropic Claude; only prompt carries context.
DESIGN: white bg #ffffff, Arial/Helvetica body 14px, Times New Roman headings,
blue links #0000cc, visited #551a8b, pre/code bg #f4f4f4 1px solid #ccc
Courier New 13px, h2 with border-bottom 1px solid #000, dense layout,
no gradients, no shadows, no rounded corners, no JS, max-width 860px centered.
NAV (pipe-separated top of page):
Home | Getting Started | Architecture | Configuration | Web Tools | Deployment | Examples | About
/index.html | /docs/getting-started.html | /docs/architecture.html | /docs/configuration.html |
/docs/web-tools.html | /docs/deployment.html | /examples.html | /about.html
TONE: Terse technical documentation prose. Direct. No marketing language.
CONTENT:
[Describe specific sections, headings, tables, code examples here]
Examples page for Rabbithole (github.com/ajbt200128/rabbithole, isarabbithole.com).
[Paste full DESIGN and NAV blocks from above]
TONE: Practical, demo-focused. Show real seed prompts and screenshots.
CONTENT: 3–5 example sites built with Rabbithole. For each: site name, seed prompt
used, link to live URL, brief description of what makes it interesting.
Include a section on example failure cases. Link to /docs/prompt-engineering.html.
Before finalizing a seed prompt or a linked-page prompt, verify:
| Item | Included? |
|---|---|
| Background color (hex) | ☐ |
| Text color (hex) | ☐ |
| Link color — normal (hex) | ☐ |
| Link color — visited (hex) | ☐ |
| Body font family + size | ☐ |
| Heading font family | ☐ |
| h1, h2, h3 styles described | ☐ |
| pre/code background + border | ☐ |
| Explicit no-gradient / no-shadow / no-border-radius (if desired) | ☐ |
| Max-width and centering | ☐ |
| Full nav: all labels + all paths | ☐ |
| Nav separator character | ☐ |
| Tone description | ☐ |
| Project name + GitHub URL + live URL | ☐ |
| Page-specific content description | ☐ |
| Instruction to copy design spec to child prompts | ☐ |
| Any specific links this page should generate (with paths) | ☐ |