# Snapshots

###### An Offline Snapshot is a static copy of your app that stays available at your Public URL while your machine is offline, so teammates or clients can review your work on their own schedule.

The common case is sharing work for review. Designers and frontend engineers send a prototype, website, or landing page to their team or to a client, who then opens it in another timezone or days later. A Snapshot keeps that link working without needing your machine to be awake.

Behind the scenes, a Public URL forwards traffic through a live connection (tunnel) to the app running on your machine. When that connection drops, because your laptop went to sleep, you quit the app, your network dropped, or you paused the Public URL, visitors would otherwise land on the branded offline page. With a Snapshot published, LocalCan serves the static copy at the same URL instead.

> [!NOTE/Availability]
> Snapshots are available on every plan, including Free. Any of your Public URLs can have a Snapshot. Each plan includes snapshot storage for your team: 150 MB on Free, 1 GB on Solo, 2 GB on Pro, and 10 GB on Teams. A published Snapshot stays up as long as your account is active. Free accounts with no activity for six months may be removed together with their Snapshots, as described in the [Terms of Service](https://www.localcan.com/terms). See your [dashboard](https://www.localcan.com/dashboard) for plan details.

#### Publishing a Snapshot

Click a Public URL in the desktop app and open **Snapshot**. On macOS, LocalCan looks at the app running behind the URL and offers two ways to publish:

* **Publish** runs your app's own build and publishes the output. LocalCan detects the app folder and the build output for you, so there is nothing to configure. This is the recommended path for most static and single-page apps, such as Vite, React, Vue, Svelte, or Astro (see the framework table below).
* **Choose Folder…** lets you publish a folder of static files yourself. Pick your project root or its built output, and LocalCan finds the `dist`, `build`, or `out` folder for you. You can also point it at a plain folder of hand-written HTML, CSS, and JS. Use this when you built the app yourself or the automatic build does not fit your setup.

On Windows the automatic build is not available, so **Publish** is not offered. Build your app yourself first, then use **Choose Folder…** and pick the project root or the built output.

Publishing takes a few seconds. When it finishes, the settings show **Last updated just now**.

#### Publishing from a folder

You can also publish without any app running. On an empty project, the desktop app shows the **Publish a static site or a prototype** card. Drop a folder on it, or click **Choose Folder…**.

<video autoPlay playsInline loop muted controls preload='none' poster="https://assets.localcan.com/blog/share-ai-prototype-with-client/drag-and-drop-publish.avif" src="https://assets.localcan.com/blog/share-ai-prototype-with-client/drag-and-drop-publish.mp4" width="1920" height="1080"></video>

The folder can be:

* **Built output**: any folder with `index.html` at its root.
* **A project root**: LocalCan finds the `dist`, `build`, or `out` folder inside it.
* **A buildable project**: if the folder has a build script, LocalCan runs the build first. Folder builds work on both macOS and Windows.

Publishing creates a new Public URL in that project and serves the folder as its Snapshot. With no app behind the URL, the Snapshot serves around the clock. When publishing finishes, LocalCan opens the URL's **Snapshot** screen, which shows **Serving your Public URL**.

To change what is served, click **Update** on the Snapshot screen. LocalCan rebuilds the project, or re-packs the folder you picked. To put a live app behind the same URL later, set the URL's target to your app's port and enable it. Visitors then reach the live app while it runs and the Snapshot when it does not.

Storage quotas and size caps are the same as for any Snapshot.

#### Supported frameworks

A Snapshot works with any framework that builds to static files. On macOS, **Publish** builds it and finds the output for you. When you build the app yourself (on Windows, or with **Choose Folder…**), choose the folder that holds the built `index.html`.

| Framework | How to snapshot |
|---|---|
| **Vite** (React, Vue, Svelte, Solid) | Automatic |
| **Next.js** | Add `output: 'export'` to `next.config.ts` |
| **Create React App** | Automatic |
| **TanStack Start** | Prerender all routes, with no server functions |
| **Astro** | Automatic |
| **SvelteKit** | Use `@sveltejs/adapter-static` with prerendering enabled |
| **Nuxt** | Prerender with `nuxi generate` |
| **Vue CLI** | Automatic |
| **Gatsby** | Automatic |
| **Docusaurus** | Automatic |
| **Eleventy** | Automatic |
| **Angular** | Automatic |

A framework that renders on the server or calls server functions at request time has no static pages to capture until you configure it for static output, as shown above. If yours is not listed, build it and choose the folder with the generated `index.html`.

#### When the Snapshot is served

The Snapshot is served only while your tunnel is offline. There is nothing to switch on per session:

* While you are online, visitors reach your live local app exactly as before.
* While you are offline, or after you pause the Public URL, visitors get the Snapshot.

Every Snapshot response carries an `X-LocalCan-Snapshot: 1` header, and a small dismissible badge appears in the corner of the page so viewers know they are looking at a static copy rather than your live app.

#### Keeping a Snapshot up to date

A Snapshot is a point-in-time copy. It does not refresh on its own. When your app changes and you want the offline copy to match:

* **Update** rebuilds (or re-packs the chosen folder) and republishes.
* **Choose Folder…** switches to a different folder.

The **Last updated X ago** label always tells you how old the current Snapshot is.

#### From the command line

The [`localcan` CLI](/docs/cli/reference) publishes and manages Snapshots without the desktop app, against a running daemon:

```bash
# Publish a folder to a new Public URL (LocalCan builds it if it is a project)
localcan snapshot publish ./my-app --name my-app

# List your Snapshots, then refresh one after your app changes
localcan snapshot ls
localcan snapshot update my-app-12.localcan.dev

# Attach a Snapshot to a Public URL you already have, or remove one
localcan snapshot add my-app-12.localcan.dev ./dist
localcan snapshot rm my-app-12.localcan.dev
```

#### From an AI agent

If you work with a coding agent such as Claude Code or Cursor, it can publish a Snapshot for you through LocalCan's [MCP server](/docs/ai-agents/mcp). The agent builds the prototype and publishes it to a link you can send for review, without leaving the chat. It uses `publish_snapshot` to create a link, `update_snapshot` to refresh it, and `get_snapshot_status` to notice when a shared link is behind your latest work. The tools that change things are off by default, so you turn them on once under Settings.

#### Requirements and limits

* The Public URL must be an HTTP LocalCan URL. Custom domains are supported.
* To protect a Snapshot with a password, use [Access control](/docs/public-urls/access-control): it is enforced on LocalCan's servers, so it covers the Snapshot as well as the live app. [Basic Auth](/docs/configuration/basic-auth) must be off, because it is checked by LocalCan running on your machine, and LocalCan will not publish a Snapshot that would end up exposed without the password you set.
* Only static output can be published. If a build has no static pages, LocalCan tells you what to change.
* A Snapshot can hold up to 5,000 files and 100 MB uncompressed.
* All Snapshots on your team count against your plan's snapshot storage quota.

#### Disabling a Snapshot

Click **Remove Snapshot**. The offline page returns for that Public URL and the stored Snapshot is removed. Deleting the Public URL removes its Snapshot as well.

