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

# Create and Publish a Page App

> End-to-end procedure to build a React page in a workspace, wire a backend automation, and publish it as an authenticated or public app.

This tutorial walks through the full lifecycle of a **page app** on Prisme.ai: a React single-page app that lives inside a workspace, talks to backend automations, and is published at a shareable URL. By the end you'll have a live page you can open at `/apps/<slug>` (inside the Platform) or `/p/<slug>` (standalone, optionally public).

It ties together three existing references:

<CardGroup cols={3}>
  <Card title="Pages" icon="window" href="/products/ai-builder/pages">
    Authoring React pages and the host contract
  </Card>

  <Card title="Automations" icon="diagram-project" href="/products/ai-builder/automations">
    Backend logic and webhook endpoints
  </Card>

  <Card title="Deployment" icon="rocket" href="/products/ai-builder/deployment">
    The Deploy modal, sharing, and embedding
  </Card>
</CardGroup>

## What You'll Build

A reusable page — for example an event "Request a demo" form — with:

* A React UI authored either in Builder or locally with the `starter-spa` repo.
* A backend automation (webhook endpoint) that receives the form submission.
* Workspace configuration for secrets (API keys) read by the automation.
* A published URL, served either to authenticated users or to anyone (public).

## Procedure

<Steps>
  <Step title="Prerequisites">
    You need a **workspace** in AI Studio (open **Create → Builder** and create one if needed) and the rights to edit it. Pick a clear **slug** for the workspace — it becomes part of the published URL (`/apps/<slug>` or `/p/<slug>`).
  </Step>

  <Step title="Author the React app">
    Choose the workflow that fits you. Both produce the same kind of bundle and use the same host contract — the default export of `src/App.tsx` is what the platform renders, and it receives `{ sdk, user, workspace, backends, agents }` as props.

    <Tabs>
      <Tab title="In Builder">
        1. In the Builder sidebar, open **Pages**.
        2. Use **+ Page → New SPA** to seed a starter React app (`src/App.tsx`, `src/main.tsx`, `src/styles/globals.css`, `index.html`, `package.json`, `vite.config.ts`).
        3. Switch to **Code** to edit the source, and **Preview** to compile and render it live.
        4. Click **Save** to sync the source files to the workspace.

        See [Pages](/products/ai-builder/pages) for the editor, preview, and host contract details.
      </Tab>

      <Tab title="Locally (starter-spa)">
        Prefer your own IDE + Git? Use the [`starter-spa`](https://github.com/prismeai/starter-spa) reference app — the same template, exported as a standalone repo.

        ```bash theme={null}
        git clone https://github.com/prismeai/starter-spa my-app
        cd my-app
        npm install
        cp .env.example .env   # PRISMEAI_API_URL + PRISMEAI_ACCESS_TOKEN + PRISMEAI_WORKSPACE_ID
        npm run dev            # local Vite dev server with a mocked host
        ```

        Edit `src/App.tsx` and preview at the local dev URL. The mocked SDK (`src/lib/mockHost.ts`) lets you iterate without deploying.

        <Tip>
          Never bundle React or `@prisme.ai/sdk` — they are provided by the host at runtime. The starter's `externals` policy handles this for you.
        </Tip>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Wire a backend automation">
    Give the page a backend to call. Create an automation exposed as a webhook endpoint:

    ```yaml theme={null}
    slug: submitForm
    name: Submit form
    when:
      endpoint: true          # public HTTP endpoint: /v2/workspaces/<id>/webhooks/submitForm
    validateArguments: true
    arguments:
      body:
        type: object
        properties:
          email: { type: string }
    do:
      - emit:
          event: form.submitted
          payload:
            email: '{{body.email}}'
      - set:
          name: $http
          value:
            status: 200
    output:
      ok: true
    ```

    From the React app, POST to that endpoint (the SDK exposes the API host):

    ```ts theme={null}
    await fetch(`${sdk.host}/workspaces/slug:<workspace-slug>/webhooks/submitForm`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email }),
    })
    ```

    See [Automations](/products/ai-builder/automations) for endpoints, events, and fetch.
  </Step>

  <Step title="Configure secrets and config">
    If the automation needs credentials (an external API key, an email service, …), store them in the workspace configuration rather than in code. Declare them under `config.value` and read them in automations with `{{config.*}}`:

    ```yaml theme={null}
    config:
      value:
        apiKey: <your-secret>
    ```

    ```yaml theme={null}
    # inside an automation
    - fetch:
        url: https://api.example.com/contacts
        headers:
          Authorization: Bearer {{config.apiKey}}
    ```

    See [Workspaces](/products/ai-builder/workspaces) for configuration and secrets.
  </Step>

  <Step title="Build and deploy">
    Turn the source into a deployed bundle.

    <Tabs>
      <Tab title="In Builder">
        Click **Deploy** in the Builder header bar. The Publish step syncs unsaved source, builds the bundle, and registers it as the workspace's current deployed bundle with a new version.
      </Tab>

      <Tab title="Locally (starter-spa)">
        ```bash theme={null}
        npm run release    # build + sync (automations + source files) + bundle + version snapshot
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Choose how it opens and who can access it">
    In the Deploy modal, two settings decide the published experience:

    **Display mode — "How should this app open?"**

    | Option          | URL            | Result                                                                   |
    | --------------- | -------------- | ------------------------------------------------------------------------ |
    | **In Platform** | `/apps/<slug>` | Wrapped in the Platform menu/shell.                                      |
    | **Standalone**  | `/p/<slug>`    | No Platform menu — the bundle owns the viewport and ships its own theme. |

    **Access mode — "Who can access this app?"**

    | Option               | Result                                         |
    | -------------------- | ---------------------------------------------- |
    | **Sign-in required** | Visitors are redirected to sign in first.      |
    | **Public**           | Anyone can open it — no Prisme session needed. |

    <Note>
      A standalone, public combination (`/p/<slug>` + Public) is the right choice for an open landing page — e.g. a QR code at an event booth that anyone can scan and submit without logging in.
    </Note>
  </Step>

  <Step title="Get the URL or embed it">
    The modal surfaces the resulting links:

    * **Platform URL** — `https://<platform-host>/apps/<slug>` (In Platform).
    * **Public URL / Standalone URL** — `https://<platform-host>/p/<slug>` (Standalone).

    To put the app inside another website instead, use the **Share** tab to generate an embed snippet (Inline, Popover, Modal, or Bottom Sheet). See [Deployment](/products/ai-builder/deployment) for embed modes and `data-*` attributes.

    <Tip>
      Reuse the same page across contexts by reading a query parameter in the app (e.g. `?event=vivatech`) and branching on it — one bundle, many landing pages.
    </Tip>
  </Step>

  <Step title="Iterate">
    To ship a change, edit the source and deploy again (**Deploy** in Builder, or `npm run release`). Each deploy creates a new version, so you can roll back from the version history if needed.
  </Step>
</Steps>

## Next Steps

<CardGroup cols={3}>
  <Card title="Pages" icon="window" href="/products/ai-builder/pages">
    Host contract, preview, and live updates
  </Card>

  <Card title="Automations" icon="diagram-project" href="/products/ai-builder/automations">
    Webhooks, events, and orchestration
  </Card>

  <Card title="Deployment" icon="rocket" href="/products/ai-builder/deployment">
    Versioning, sharing, and embedding
  </Card>
</CardGroup>
