# How to Generate Multi-Page Websites from a Single Prompt Using stitch-loop

> Learn how to generate multi-page websites from a single prompt using stitch-loop. Discover the autonomous baton-passing workflow for efficient site creation.

- Repository: [Google Labs Code/stitch-skills](https://github.com/google-labs-code/stitch-skills)
- Tags: how-to-guide
- Published: 2026-07-18

---

**The stitch-loop skill implements an autonomous "baton-passing" workflow where an agent iteratively generates pages by reading task instructions from [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md), creating screens via Stitch MCP tools, and writing a new baton file to trigger the next iteration until the site is complete.**

The `stitch-loop` skill in the `google-labs-code/stitch-skills` repository enables autonomous, prompt-driven generation of multi-page websites through a stateless coordination mechanism. By leveraging a markdown-based "baton" system and design-system constraints stored in [`.stitch/DESIGN.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/DESIGN.md), this approach allows AI agents to iteratively build cohesive websites without human intervention between pages.

## Understanding the stitch-loop Baton System

At the core of multi-page website generation is the **Baton System**: a simple markdown file located at [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md) that carries the current task state between iterations. Unlike complex orchestration frameworks, this approach uses version-controlled files for coordination, making the process reproducible and audit-able.

The baton file contains YAML front-matter specifying the target `page` and a markdown body containing the prompt instructions. According to the schema defined in [`plugins/stitch-utilities/skills/stitch-loop/resources/baton-schema.md`](https://github.com/google-labs-code/stitch-skills/blob/main/plugins/stitch-utilities/skills/stitch-loop/resources/baton-schema.md), each baton must include the design system block to ensure visual consistency across generated pages.

## The 7-Stage Multi-Page Generation Workflow

The stitch-loop skill executes a deterministic pipeline defined in [`plugins/stitch-utilities/skills/stitch-loop/SKILL.md`](https://github.com/google-labs-code/stitch-skills/blob/main/plugins/stitch-utilities/skills/stitch-loop/SKILL.md). Each loop iteration performs the following stages:

### 1. Read the Baton

The agent parses [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md) to extract the YAML front-matter (`page:` field) and the markdown body containing the generation prompt. This file acts as the single source of truth for the current iteration's objective.

```markdown
---
page: about
---
A page describing how the company's tracking works.

**DESIGN SYSTEM (REQUIRED):**
[Copy from .stitch/DESIGN.md Section 6]

**Page Structure:**
1. Header with navigation
2. Explanation of tracking methodology
3. Footer with links

```

### 2. Load Context

The skill reads [`.stitch/SITE.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/SITE.md) (containing site vision, sitemap, and roadmap) and [`.stitch/DESIGN.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/DESIGN.md) (the design-system block). These files provide the agent with architectural constraints and visual guidelines necessary for coherent multi-page generation.

### 3. Generate with Stitch

Using MCP tools defined in the skill configuration, the agent calls `create_project` (or retrieves an existing project ID from [`.stitch/metadata.json`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/metadata.json)) followed by `generate_screen_from_text`. The full prompt includes the design-system block copied from [`.stitch/DESIGN.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/DESIGN.md) to prevent visual drift.

Results are saved to `.stitch/designs/{page}.html` and `.stitch/designs/{page}.png` for temporary storage before integration.

### 4. Integrate Assets

The skill moves the generated HTML from `.stitch/designs/` to `site/public/{page}.html`, fixes relative asset paths, and wires navigation links by replacing placeholder `href="#"` attributes with actual page references.

### 5. Optional Visual Verification

If a Chrome DevTools MCP server is available, the agent can spawn a local development server, navigate to the new page, capture a screenshot, and perform pixel-comparison against the Stitch-generated reference image in `.stitch/designs/`.

### 6. Update Site Documentation

The skill automatically amends [`.stitch/SITE.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/SITE.md) to reflect the new page in the Sitemap section, removes the consumed idea from the "Creative Freedom" section, and updates the Roadmap if a backlog item was completed during this iteration.

### 7. Write the Next Baton

**This step is mandatory**—without it, the loop halts. The skill generates a fresh [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md) containing the next `page:` value and a new prompt, effectively passing the baton to the next iteration.

```python

# Pseudocode representing the skill's orchestration logic

next_baton = f"""---
page: achievements
---
A competitive achievements page showing developer badges.

**DESIGN SYSTEM (REQUIRED):**
{design_system_block}

**Page Structure:**
1. Header with navigation
2. Badge grid with unlocked/locked states
3. Progress bars for milestones
"""
write_file('.stitch/next-prompt.md', next_baton)

```

## Required Configuration Files

Successful multi-page generation depends on four critical files in the `.stitch/` directory:

### .stitch/next-prompt.md (The Baton)

This file adheres to the JSON schema in [`plugins/stitch-utilities/skills/stitch-loop/resources/baton-schema.md`](https://github.com/google-labs-code/stitch-skills/blob/main/plugins/stitch-utilities/skills/stitch-loop/resources/baton-schema.md). It must contain valid YAML front-matter with a `page` key and a markdown body describing the desired output.

### .stitch/SITE.md (Site Context)

A markdown file tracking the site vision, sitemap completion status, and roadmap backlog. The skill parses this to understand what pages exist and what remains to be built.

```markdown

# Site Vision

My Awesome Product

## 4. Sitemap

- [x] index.html
- [ ] about.html   <!-- will be filled by the loop -->

## 5. Roadmap

- Create an "Achievements" page
- Add a "Pricing" page

```

### .stitch/DESIGN.md (Design System)

Contains the design-system block (typically Section 6) that gets injected into every generation prompt. This ensures all pages share the same color palette, typography, and component structure.

### .stitch/metadata.json (State Persistence)

Records project IDs and screen metadata to enable later edits without recreating projects:

```json
{
  "projectId": "6139132077804554844",
  "screens": {
    "index": { "id": "...", "width": 390, "height": 1249 },
    "about": { "id": "...", "width": 390, "height": 1159 }
  }
}

```

## Implementing the stitch-loop Workflow

To initiate multi-page generation:

1. Run the `design-md` skill once to create [`.stitch/DESIGN.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/DESIGN.md)
2. Create an initial baton at [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md) targeting your first page
3. Execute the stitch-loop skill via Stitch MCP or CLI
4. Allow iterations to continue until the roadmap is exhausted

```python

# Complete workflow pseudocode from SKILL.md

def run_stitch_loop():
    # Stage 1: Read baton

    baton = read_file('.stitch/next-prompt.md')
    page = extract_yaml(baton)['page']
    prompt = extract_markdown_body(baton)
    
    # Stage 2: Load context

    design = read_file('.stitch/DESIGN.md')
    site = read_file('.stitch/SITE.md')
    
    # Stage 3: Generate

    full_prompt = f"{prompt}\n\n**DESIGN SYSTEM:**\n{design}"
    project_id = get_or_create_project()
    screen = generate_screen_from_text(project_id, full_prompt, device='DESKTOP')
    
    # Stage 4: Integrate

    download(screen.htmlUrl, f'site/public/{page}.html')
    fix_asset_paths(f'site/public/{page}.html')
    
    # Stage 5: Update documentation

    update_site_md(site, page)
    
    # Stage 6: Write next baton (triggers next iteration)

    create_next_baton(site.roadmap.pop())

```

## Automating with CI/CD

The stateless nature of the baton file makes stitch-loop ideal for GitHub Actions automation. Trigger new iterations when the baton file changes:

```yaml
name: Stitch Loop
on:
  push:
    paths:
      - '.stitch/next-prompt.md'
jobs:
  run-loop:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run stitch-loop skill
        run: stitch-skill run stitch-loop

```

## Summary

- The **baton file** ([`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md)) provides stateless coordination between generation iterations
- **Design consistency** is enforced by injecting [`.stitch/DESIGN.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/DESIGN.md) into every prompt passed to `generate_screen_from_text`
- The ** seven-stage pipeline** handles everything from context loading to navigation wiring automatically
- **Metadata persistence** in [`.stitch/metadata.json`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/metadata.json) prevents duplicate project creation and enables iterative refinement
- **Orchestration-agnostic architecture** allows the loop to run via CLI, GitHub Actions, or chained agent systems

## Frequently Asked Questions

### What is the baton file in stitch-loop?

The baton file is a markdown document stored at [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md) that contains YAML front-matter specifying the target page and a prompt body describing what to generate. It serves as the state carrier between loop iterations, allowing the skill to know what to build next without requiring an external database or state store.

### How does stitch-loop maintain design consistency across multiple pages?

According to the implementation in [`plugins/stitch-utilities/skills/stitch-loop/SKILL.md`](https://github.com/google-labs-code/stitch-skills/blob/main/plugins/stitch-utilities/skills/stitch-loop/SKILL.md), the skill automatically appends the full design-system block from [`.stitch/DESIGN.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/DESIGN.md) to every prompt sent to the Stitch MCP tools. This ensures that color schemes, typography, and component styles remain identical across [`index.html`](https://github.com/google-labs-code/stitch-skills/blob/main/index.html), [`about.html`](https://github.com/google-labs-code/stitch-skills/blob/main/about.html), and all other generated pages.

### Can stitch-loop run fully autonomously in CI/CD pipelines?

Yes. Because the skill relies on file-based state (the baton document and [`.stitch/metadata.json`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/metadata.json)) rather than in-memory state, it integrates seamlessly with GitHub Actions or other CI systems. Each push to [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md) can trigger a workflow that executes one iteration of the loop, generating a page and writing a new baton to trigger the next build.

### What happens if the stitch-loop process is interrupted?

If the loop stops—whether due to an error, manual termination, or missing next-baton write—the workflow simply halts. The already-generated pages remain in `site/public/`, and the current baton stays in [`.stitch/next-prompt.md`](https://github.com/google-labs-code/stitch-skills/blob/main/.stitch/next-prompt.md). To resume, fix any issues and ensure the baton file exists with the correct schema; the next execution will pick up exactly where the previous iteration left off.