Help and guides

Preview and publish a site

Check a private preview and review the exact release before it goes live.

Before you start

Your organization needs a configured site and repository. Builds and publication must be available for that site. Preview access and live publication are separate steps.

Steps

  1. Open Sites and select your site.
  2. In Settings, check Live branch, Preview branch, and Signed-in preview hostname. Use Save deployment settings if you change them.
  3. Choose Build preview and wait for the preview to be ready.
  4. Choose Open signed-in preview. Sign in again if asked, then review the site.
  5. For a live release, build the live branch first. When Review live release is available, check the exact release and destination before choosing Approve exact live release.

What to expect

A preview stays private. A live release is complete only when its deployment finishes and the live site responds as expected.

If something goes wrong

If the dashboard says Build the live branch before publishing, the preview is not eligible for that live release. If setup or approval is required, complete the indicated step. A private test site does not have automatic permission to publish publicly.

Technical reference

Connect a source repository

Sites builds the Dockerfile in your repository and runs that image, so a Vite or Next.js static export served by a static file server and a Node server are both supported; anything that uses databases or application services must be a server process. The container listens on 0.0.0.0 at the app's port: 8080 for sites created with the Sites workflow tools (thora_sites_site_read returns port), or the port chosen when a repository was connected. Any Node 22 or newer image works. A Sites target records the repository, branch, Dockerfile, context, application port, and pinned host key where required. HTTPS repository URLs must not contain credentials. Private SSH connections return a per-app public deploy key that the repository owner must add with write access disabled; private key material remains server-side.

  • Connecting a repository allocates no public domain and deploys nothing.
  • Managed repository IDs come from thora_git_read (or a site's managed_repository_id in thora_sites_site_read). Workflow tools never take a repository ID, so agents should not ask users for one.
  • The thora_sites_workflow_* tools exist only on the hosted Thora connector, not the local stdio connector.
  • Private deploy requests use a stable deployment ID after uncertain results.
  • Once a public domain is connected, agent-only private deployment is refused so public changes remain reviewable.

Build and review a signed-in preview

When Sites assigns a Thora preview hostname (s- followed by 32 random characters, under preview.thoracloud.com), you can build and open a signed-in private preview on it. No domain setup is needed. To publish live, connect a domain your organization owns.

A preview build runs the selected Git branch in an isolated guest and checks HTTP readiness without changing the live domain. Sites shows the exact built commit and deployment ID. When the preview is ready, sign in at https://beta.thora.cloud/dashboard/sites, select the site-owning organization, and click Open signed-in preview on its card. Opening the preview hostname directly returns 403 until the dashboard establishes a short-lived session.

  • Use one stable deployment ID and reconcile an uncertain response before retrying.
  • A failed candidate leaves the previous serving deployment in place.
  • Source edits happen in Git. Qualified managed Git agent tools can commit bounded changes before a new build.
  • Agents can inspect with thora_sites_preview_access, but must give humans the dashboard link instead of the ticket URL.

Set your live hostname early

Open the site's Domains tab and save its intended live hostname, or use thora_sites_domain_configure with appId, domain and the current config_version as expectedVersion. No deployment, commit, DNS record or certificate is needed to save this setup. The hostname must be under a domain verified in the same organization and unused by another site. Saving keeps the site private; publication is a separate review of an exact built release.

Sites read distinguishes configured_domain (intended hostname) from domain (currently published hostname). Set domain to null to clear a draft hostname; this cannot unpublish a live site. Identical retries do not consume the hostname-change allowance. Actual changes are limited to 20 per site and 60 per organization per rolling hour; respect Retry-After when limited.

A Thora preview hostname needs no DNS records; keep it unchanged in settings. It is never a live hostname. When new Thora preview hostnames are available, saving preview settings with previewDomain null switches a site to one. For a custom signed-in preview, use a different verified hostname. Before saving preview settings, set its A record to 209.126.127.200 and remove conflicting AAAA records or DNS proxying. Missing or unresolved records return dns_pending instead of a compute outage. Temporary resolver failures return dns_verification_unavailable with a 30-second retry interval. No build or publication is queued by a refused settings request.

MCP hostname setup before a buildjson
{"name":"thora_sites_domain_configure","arguments":{"appId":"a1111111-1111-4111-8111-111111111111","domain":"www.example.com","expectedVersion":1}}

Publish to an owned domain

Saving a hostname does not publish. Public Sites require a verified domain and a signed-in administrator to review the built commit, deployment, and hostname. A scoped Sites agent can request public domain attachment or live redeploy; the request appears in the Thora notifications menu, and its review link opens that exact request. A check or X decides it. Private MCP deployment remains available before a domain is attached. Check DNS, TLS, and page content before calling a site live.

Make a live site private

A site can require a Thora sign-in before anyone reads it. Locking takes effect directly, with no approval, and works before a site is published. Every live hostname, page, asset and API route then requires a sign-in by a member of the site's organization; everyone else sees a plain no-access page. Inbound webhooks and integrations such as payment, form or chat callbacks and uptime monitors cannot sign in, so they cannot reach a private site, and there is no allow-list yet. Copies already saved in a visitor's browser can stay viewable on that device until they expire. A sign-in to the site lasts 10 minutes; opening or reloading a page after that checks the person's Thora sign-in and membership again without asking them to sign in while they stay signed in to Thora. Background requests made after the 10 minutes get HTTP 401 with the header X-Thora-Site-Session: reauthentication-required, so a dashboard or single-page app should reload the page when it sees that response. Someone removed from the organization cannot sign in again, but they can keep access to the private site for up to 10 minutes. An already-open live connection, such as a WebSocket or streaming response, can stay open for up to about 20 minutes. Making the site public again always needs an organization administrator's approval in Thora.