Structuring Your App

Surfaces

Give one app several mini apps, such as a booking site and a staff POS, each with its own URL, icon and access.

A Surface is a distinct experience inside one app. To its users it feels like its own mini app, with its own name, generated URL, icon and PWA identity, launch behavior, and public or internal access.

Surfaces live inside one product. They are not separate Stardeck apps and not Modules. Modules are reusable capabilities. Surfaces are how people open and use parts of the product. See One Product, One App.

Add a Surface

1

Ask for the experience

Ask your coding agent, for example for a POS for iPads or an internal admin. Say which audience and device it is for, and whether it is public or internal. The agent declares the Surface in code, following the app's AGENTS.md. If you build in the browser, ask Starcat Developer in the app's Build tab.

2

Review it

Try it in the sandbox or a branch preview. Its own URL comes later, with the production deploy.

3

Sync the Surface

Once the change is on the default branch and its sandbox runs that commit, click Sync surfaces in Settings → Deployments → Production so the dashboard discovers it. Your agent can do this with sync_app_branch_surfaces.

4

Deploy

Deploy the app so ready Surfaces go live. See Publishing & Deployment.

5

Open it

Open a live Surface from its row, or from its tab in the app frame.

Where Surfaces appear

Surfaces are rows in Settings → Deployments → Production. Common states:

Row stateMeaning
Live (shows a URL)Served on production. Open it from the row.
Ships on next deployDeclared on the branch. Not live until you deploy.
Removed at tipRemoved from the branch tip. It stays live until you deploy the removal.

Each row's ⋯ menu has Show app shell. When it is off, opening the Surface from Stardeck skips the shell and goes straight to its own URL. Live Surfaces also appear as tabs in the app frame.

A Surface can appear in the dashboard soon after it reaches the default branch. Its launch URL becomes usable after a production deploy.

Access and project visibility

Surface access is either public or internal. Project visibility still wins:

Project visibilitySurface accessEffective outcome
PublicPublicPublic Surface URL
PublicInternalInternal Surface URL; signed-in team members can enter
Internal or privatePublicStill internal: project visibility dominates
Internal or privateInternalInternal Surface URL

There is no per-Surface private access setting. Private stays an app-level visibility choice. See App Visibility for the full rules.

Warning:

Internal is authentication, not admin authorization. Any signed-in team member can open an internal Surface. App users cannot: they sign in only to the deployed app and do not have Stardeck team access. If only some team members should use the Surface (for example managers only), ask the agent to add an in-app permission check on that Surface. API routes used by the Surface authorize separately. They are not covered by the Surface access setting alone.

Publish, URLs, and launch identity

  • One app publish ships all ready Surfaces together.
  • Non-root Surface hosts are production-only in the current release. Preview keeps working inside the sandbox; dedicated Surface URLs appear after production deploy.
  • The root Surface uses the app's primary host (including any custom domain bound to that host).
  • Non-root Surfaces use their generated Stardeck Surface URLs. There is no per-Surface custom-domain picker.
  • If you need an internal experience on the root of a public app, make the whole app internal instead. An internal root Surface in a public app cannot receive the separate edge boundary.

Each Surface can have its own PWA name, icon, and launch path. Internal Surfaces can also override Show app shell so a pinned iPad or phone experience opens without Stardeck chrome. See Add to Home Screen.

Example: restaurant

One restaurant system app with four Surfaces:

SurfaceAudienceAccess
Customer orderingDiners and takeoutPublic
POSCounter staff on iPadsInternal, plus staff permission check
Kitchen displayKitchen teamInternal, plus kitchen permission check
Back officeManagersInternal, plus manager permission check

They share the menu, orders and release cadence, so they belong in one app. Ask your agent:

Build a restaurant system with shared menu and orders. Add four Surfaces:
1) public customer ordering, 2) internal POS for iPads, 3) internal kitchen display,
4) internal back office for managers. Staff Surfaces should require the right roles;
internal access alone is not enough.

Follow-ups:

Make the POS open straight into the order screen and use a clear home-screen icon for iPads
On the kitchen display, show open tickets and let the kitchen mark items ready

To keep the whole system off the public internet, make the app internal or private.

Publish once:

  1. Review each Surface in preview.
  2. Merge the change, then click Sync surfaces in Settings → Deployments → Production. Declared Surfaces read Ships on next deploy.
  3. Click Review & Deploy there. One deploy ships all ready Surfaces.
  4. When a row shows a live URL, open it. For iPad POS or kitchen tablets, turn Show app shell off and add it to the home screen.

A service business works the same way: marketing site, customer portal and staff admin as Surfaces of one booking app.

If the next experience needs its own ownership, tenant boundary or release cadence, see When to Create a Separate App.