---
title: Publishing
description: The bundle shape sherpage_publish expects, and the tools that update, archive, and delete a page afterward.
---

# Publishing

A page is created from an in-memory bundle — no files ever have to
touch disk on your side. Each file in the bundle is:

```json
{ "path": "index.html", "content": "<html>…</html>", "encoding": "utf8" }
```

`encoding` is `utf8` for text or `base64` for binary content — an image
or a font, for example. `path` is bundle-relative; anything that tries
to escape the bundle (a leading `/`, `..`, a backslash) is rejected as
an unsafe path rather than silently normalized. Every file's extension
must be one sherpage recognizes — `html`, `css`, `js`, `json`, `txt`,
`svg`, `png`, `jpg`, `jpeg`, `webp`, `gif`, `woff2` — since the content
type served is taken from the extension, never sniffed from the bytes.

A bundle is capped at 100 files, 10 MB per file, and 50 MB total;
exceeding any of them is a `413`, not a truncated upload.

```
sherpage_publish({
  title: "My prototype",
  files: [{ path: "index.html", content: "…", encoding: "utf8" }],
  access: "public",
})
```

`entrypoint` defaults to `index.html` — the file served at the page's
own root — and can name a different file if your bundle doesn't have
one. `slug`, `expiresAt`, `maxViews`, `password`, and `allow` are all
optional at publish time and can be changed later.

## After publishing

- `sherpage_update` changes title, slug, expiry, or view budget.
- `sherpage_set_access` changes the access level (and password, if
  applicable) — see [access modes](/concepts/access-modes).
- `sherpage_archive` takes a page out of active use, or restores one.
- `sherpage_delete` permanently deletes the page and its files —
  irreversible, and requires `confirm` to exactly match the page's id.

## Next

[The p. url](/sherpage/the-p-url).
