Docusaurus & static builds

thin.host hosts the output of any static-site generator — Docusaurus, Astro, Vite, VitePress, Hugo, Next output: 'export' — and an agent can deploy it in one tool call. This page is the Docusaurus recipe; the same flow works for the others. Prefer to hand this to Claude Code? Install the thin-host-docusaurus skill (curl -o ~/.claude/skills/thin-host-docusaurus/SKILL.md --create-dirs https://thin.host/skills/thin-host-docusaurus/SKILL.md) and say "deploy my docs".

What you get

1. Decide the baseUrl

Docusaurus bakes baseUrl into every asset URL. Where the site will be viewed decides the value:

Where readers will lookbaseUrlNotes
A custom domain, e.g. docs.example.com/The normal case. The thin.host preview URL renders unstyled until the domain is mapped — expected, not a bug.
The preview URL https://thin.host/s/<slug>//s/<slug>/Pick the slug first and pass it to publish_website.

Make it switchable so both builds come from one repo:

// docusaurus.config.ts
url: 'https://docs.example.com',
baseUrl: process.env.DOCUSAURUS_BASE_URL ?? '/',
# custom-domain build (default)
npm run build

# preview build for the shared thin.host origin
DOCUSAURUS_BASE_URL=/s/example-docs/ npx docusaurus build --out-dir build-preview

The publish tools detect Docusaurus and report base_url. When it will not resolve at the returned URL the response carries a warning that says exactly this — an agent should relay it rather than debug a "blank" site.

2. Publish

publish_website(
    source_path="/abs/path/to/repo/build",
    title="Example Docs",
    slug="example-docs",   # needed if you built with baseUrl '/s/example-docs/'
)
# → { url: "https://thin.host/s/example-docs/", page_count: 277, asset_count: 400,
#     requests: 5, framework: "docusaurus", base_url: "/", warning: "…" }

Or from Claude Code, in words: "Build the docs and publish the build folder to thin.host as example-docs."

3. Redeploy with sync

update_website(
    website="example-docs",              # slug, id, or live URL
    source_path="/abs/path/to/repo/build",
    sync=True,
)
# → { removed_assets: ["/assets/js/main.0a1b2c3d.js", …], kept_redirects: [], … }

Always pass sync=true for a build folder. Without it the site keeps working, but every previous build's chunks stay forever. Sync is safe to re-run; a deploy that fails partway says which request failed, and running it again finishes the job.

No local server? Publish a zip

Through the hosted endpoint (https://thin.host/mcp, or any agent without a local MCP server) the build travels as a zip. Either upload it directly:

cd build && zip -qr ../site.zip . && cd ..
curl -X POST https://thin.host/v1/websites/example-docs/archive \
  -H "Authorization: Bearer $THIN_HOST_API_KEY" -F file=@site.zip     # sync=true by default

…or put the zip somewhere public and let the agent call publish_website_from_url / update_website_from_url with that link. Both apply the same mapping, baseUrl detection and sync rules as the local tools.

4. Map the domain

Dashboard → the website → Domains → add docs.example.com and create the CNAME shown. TLS provisions automatically, secondary hostnames 301 to the primary, and robots.txt / sitemap.xml are generated for the domain. An agent can instead call provision_domain and hand the user the claim URL.

Protecting the docs

Password- or email-gate the whole site, or single pages, from the dashboard. Gating is stored on the page, and a redeploy updates pages in place, so it survives. Leave /404 unprotected — a gated 404 page is not used for misses.

REST, for CI

Everything above is three endpoints. Split the build into batches of at most 20MB, 200 pages, and 500 assets each:

# create (first batch) → note the slug
curl -X POST https://thin.host/v1/websites -H "X-Platform-API-Key: $THIN_HOST_API_KEY" \
  -H "Content-Type: application/json" -d @batch-0.json

# remaining batches — assets first, then pages
curl -X PATCH https://thin.host/v1/websites/example-docs -H "X-Platform-API-Key: $THIN_HOST_API_KEY" \
  -H "Content-Type: application/json" -d @batch-1.json

# prune with the full manifest
curl -X POST https://thin.host/v1/websites/example-docs/sync -H "X-Platform-API-Key: $THIN_HOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"keep": {"pages": ["/", "/docs/intro", "/404"], "assets": ["/assets/js/main.e7f12ca1.js", "…"]}}'

Full field reference: REST API · MCP tools.

Supported files

.html files become pages (docs/intro/index.html/docs/intro, 404.html/404). Assets: css, js, mjs, map, png, jpg, jpeg, gif, svg, ico, webp, avif, mp4, webm, mp3, woff, woff2, ttf, otf, eot, wasm, json, xml, txt, csv, md, yaml, yml, pdf, webmanifest. Anything else (for example .nojekyll) is skipped and listed in skipped_files. Single files over ~15MB do not fit a request — compress or drop them.