{"topic":"section-cookbook","content":"# File bundle cookbook\n\nSecondPage publishing accepts static file bundles, not renderer sections.\n\n## Minimum page\n\n```json\n{\n  \"title\": \"Project Brief\",\n  \"files\": [\n    {\n      \"path\": \"index.html\",\n      \"content_type\": \"text/html; charset=utf-8\",\n      \"content_base64\": \"PCFkb2N0eXBlIGh0bWw+PGh0bWw+Li4uPC9odG1sPg==\"\n    }\n  ]\n}\n```\n\n## Multi-file app\n\nUse normal relative asset references from `index.html`:\n\n```html\n<link rel=\"stylesheet\" href=\"styles.css\">\n<script src=\"app.js\" defer></script>\n<img src=\"assets/chart.png\" alt=\"Revenue chart\">\n```\n\nThen submit all referenced files:\n\n```json\n{\n  \"title\": \"Interactive Dashboard\",\n  \"entrypoint\": \"index.html\",\n  \"files\": [\n    { \"path\": \"index.html\", \"content_type\": \"text/html; charset=utf-8\", \"content_base64\": \"...\" },\n    { \"path\": \"styles.css\", \"content_type\": \"text/css; charset=utf-8\", \"content_base64\": \"...\" },\n    { \"path\": \"app.js\", \"content_type\": \"text/javascript; charset=utf-8\", \"content_base64\": \"...\" },\n    { \"path\": \"assets/chart.png\", \"content_type\": \"image/png\", \"content_base64\": \"...\" }\n  ]\n}\n```\n\n## Semantic edit targets\n\nFor fresh generated pages, stamp important editable regions with stable names.\nUse readable `id`, useful `aria-label`, and `data-review-target-id` attributes\non sections, hero blocks, headings, CTAs, repeated cards, charts, tables, forms,\nnav items, and deck frames. These markers help Turner understand comments like\n\"make this card more premium\" or \"rewrite this CTA\" without guessing from a\ngeneric `<div>`.\n\n```html\n<section id=\"hero\" data-review-target-id=\"hero\" aria-label=\"Hero section\">\n  <h1 id=\"hero-heading\" data-review-target-id=\"hero-heading\">Launch plan</h1>\n  <a id=\"hero-primary-cta\" data-review-target-id=\"hero-primary-cta\" href=\"#contact\">\n    Book a walkthrough\n  </a>\n</section>\n```\n\n## Deck bundle\n\nFor new decks, prefer `prepare_deck`; it creates this supported structure\nwithout changing slide HTML:\n\n```html\n<!doctype html>\n<html data-sp-document-type=\"deck\">\n  <body>\n    <main data-secondpage-deck data-sp-canvas-width=\"1280\" data-sp-canvas-height=\"720\">\n    <section id=\"sp-slide-slide-1\" data-sp-frame data-sp-slide-id=\"slide-1\">\n      <h1>Opening idea</h1>\n    </section>\n    <section id=\"sp-slide-slide-2\" data-sp-frame data-sp-slide-id=\"slide-2\">\n      <h1>Second idea</h1>\n    </section>\n    </main>\n  </body>\n</html>\n```\n\nEvery slide root needs a stable `data-sp-slide-id`. Publish with\n`presentation: { \"intent\": \"deck\" }`. A successful publish is not readiness\nevidence; only `presentation.status: \"ready\"` verifies presentation controls for\nthat version.\n\n## Updating safely\n\n1. Read the current complete bundle. If `file_bundle` is null, export it and\n   retain the exported version ID and manifest; verify referenced file bytes\n   before editing.\n2. For a default-route bundle, submit every file with the matching\n   `base_version_id`.\n3. For custom entrypoints or routes, follow [Publishing and revisions](publishing-shape.md)\n   and preserve the manifest in both signed-upload calls. If the client cannot\n   PUT files, hand off that upload.\n4. On `version_conflict`, re-read/export and reconcile before retrying.\n\nDo not send only the changed file. Updates are full bundle replacements.\n\n## Practical guidance\n\n- Use `index.html` as the entrypoint unless there is a strong reason not to.\n- Keep asset paths stable between versions when possible.\n- Put generated CSS and JS in separate files for easier future updates.\n- Inline only tiny assets. Use `create_media_upload` for larger images or\n  original video files, and keep normal CSS/JS/fonts/data as separate bundle\n  files when they fit the payload limits.\n- When using direct media uploads, reference the returned `asset_url` in HTML\n  and pass the completed IDs as `media_asset_ids` on `create_page` or\n  `update_page` when you want explicit claiming.\n- If the user gave you an existing HTML export, publish the export as-is rather\n  than translating it into a SecondPage-specific structure.\n"}