> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tappify.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Local server during live preview

> Expose your local extension server through a tunnel so the host can call it while you edit.

During a live preview Tappify calls your server from its own servers, so `http://localhost:8787`
is not an address it can reach. Run the handler with `pnpm run dev:worker`, put a tunnel in front
of it, and pass the public URL to the dev session.

```bash theme={null}
tappify extension dev --live --server https://your-tunnel.example.com
```

<Tabs>
  <Tab title="cloudflared">
    ```bash theme={null}
    brew install cloudflared
    cloudflared tunnel --url http://localhost:8787
    ```

    It prints a `https://<random>.trycloudflare.com` URL. That is the value for `--server`.
  </Tab>

  <Tab title="ngrok">
    ```bash theme={null}
    brew install ngrok
    ngrok http 8787
    ```

    Use the `Forwarding` line's `https` URL for `--server`.
  </Tab>
</Tabs>

<Steps>
  <Step title="Start your server">
    ```bash theme={null}
    pnpm run dev:worker
    ```

    Wrangler serves `server/worker.ts` on `http://localhost:8787`. A Node or Express handler is
    the same idea on its own port.
  </Step>

  <Step title="Start the tunnel">
    One of the commands above, in a terminal of its own. Copy the `https` URL.
  </Step>

  <Step title="Start the dev session with the URL">
    ```bash theme={null}
    tappify extension dev --live --server https://your-tunnel.example.com
    ```

    The server, the tunnel and the session each hold a terminal, so this is the third.
  </Step>

  <Step title="Confirm the tunnel reaches it">
    ```bash theme={null}
    curl https://your-tunnel.example.com/tappify/health
    ```

    The starter answers `{"ok":true,"version":"0.1.0"}`. Health is the one route that needs no
    token, which is why it is the check to run first.
  </Step>
</Steps>

## What Tappify sends through the tunnel

Every call carries an install token audienced to your extension, an idempotency header, the
project context and the page's current filters, plus your install's stored documents and the
owner's credentials when your manifest declares `connector.auth`. That is the same shape production sends, so a procedure that works through the
tunnel works after publish.

## Notes

* The tunnel URL changes each time you restart it on the free tiers. Restart the dev session with
  the new URL, or use a named tunnel.
* `--server` sets the URL for this session only. It does not change your manifest. Set the
  permanent value with `tappify extension set server.sandboxBaseUrl <url>`.
* A `http://localhost` URL is accepted and then fails, because the call comes from Tappify's
  servers rather than your machine. Any other host has to be `https`.
* A response has 30 seconds and 1 MB. A tunnel adds latency at both ends, so test near the limit
  before you rely on it.
