Skip to content

Ship public state to production ​

In the earlier tutorials you pushed public state to the development environment and read it from an app. Real apps serve people from production. This tutorial explains how SkyState environments work, then takes you through one promotion end to end: preview the change, then apply it to move the welcomeText key from staging to production.

Estimated time: 15 minutes.

What you'll build ​

You carry the welcomeText key from a tutorial track through to production:

  • Wire the provider so a build variable picks the environment, instead of a value fixed in the source.
  • Enable end-user auth for the project and register callback URLs for deployed environments, so sign-in and user state keep working outside local development.
  • Push a staging welcome message with the CLI.
  • Preview the promotion with sky state public promote --dry-run before anything is written.
  • Apply the promotion at the confirmation prompt, and check the result in production.
  • See where --yes and --comment fit for automation and audit trails.

Prerequisites ​

  • One tutorial track: React, Vanilla, or API. You need its project created and welcomeText being read from public state.
  • The SkyState CLI, signed in with sky login.

Step 1: Understand the environment model ​

Every project has three fixed environments, and every command selects one through --env (aliases dev, stg, and prod resolve to the full names). See Environments for the model; this tutorial uses promote to copy public state from staging to production.

Step 2: Pick the environment from a build variable ​

You wired the environment as development for the first run. A production build should reach production, so drive the environment prop from a build variable instead of fixing it in the source. Update the provider in src/main.tsx (replace YOUR_ACCOUNT_ID with the ACCOUNT ID from sky status):

tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import { SkyStateProvider } from '@skystate/react'
import App from './App.tsx'

const skyStateEnv = import.meta.env.VITE_SKYSTATE_ENV ?? 'development'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <SkyStateProvider
      account="YOUR_ACCOUNT_ID"
      project="tutorial-app"
      environment={skyStateEnv}
      callbackUrl={window.location.origin}
    >
      <App />
    </SkyStateProvider>
  </StrictMode>,
)

VITE_SKYSTATE_ENV is a name you choose; set it to development, staging, or production per build (on the Vanilla or API track, pass the same value where you set the environment). See SkyStateProvider for prop detail and Environments for choosing the value.

Step 3: Register deployed callback URLs ​

Public state does not need sign-in. If your app also reads user state, that needs sign-in, and sign-in needs two things: end-user auth enabled on the project, and a callback URL for each deployed environment.

On the React track, Part 2 registered http://localhost:5173 for development only. Register the deployed staging and production URLs before you test sign-in there:

bash
sky project auth callback-urls add \
  --project tutorial-app \
  --url https://your-staging-app.example.com \
  --env staging

sky project auth callback-urls add \
  --project tutorial-app \
  --url https://your-production-app.example.com \
  --env production

sky project auth enable --project tutorial-app

Enabling end-user auth is project-scoped, so it takes no --env and is done once per project. If you already enabled it during your track, skip that command.

Register the exact URL your app passes as callbackUrl. This tutorial passes window.location.origin, so register the bare origin each deployed build serves from, as you did for http://localhost:5173 in development. The full matching rule is on the CLI reference: Callback URL matching.

Step 4: Push a staging welcome message ​

Set welcomeText in staging. This is the state you promote to production next.

bash
sky state public push \
  --json '{"welcomeText":"New dashboard is live. Try it now."}' \
  --project tutorial-app \
  --env staging \
  --comment "Prepare welcome text for production launch"

Confirm it landed:

bash
sky state public show --project tutorial-app --env staging

Step 5: Preview the promotion ​

A dry-run shows the change without writing it:

bash
sky state public promote \
  --project tutorial-app \
  --from staging \
  --to production \
  --keys welcomeText \
  --dry-run

--keys welcomeText limits the promotion to that one top-level key. The output lists every change it would make: here, a single addition, since production has no state yet. The dry-run exits without writing anything.

TIP

Use diff when you only want to compare two environments, without preparing a promotion:

bash
sky state public diff \
  --project tutorial-app \
  --from staging \
  --to production \
  --keys welcomeText

It prints the public-state differences and never writes to either environment.

Step 6: Apply the promotion ​

Run the same command without --dry-run. The CLI recomputes the changes, shows them as a diff, and asks you to confirm:

bash
sky state public promote \
  --project tutorial-app \
  --from staging \
  --to production \
  --keys welcomeText \
  --comment "Promote launch welcome text to production"
Apply all changes? [y/N]

Confirm with y. The CLI applies the changes and prints the environment, the number of changes, and the new version number.

Verify ​

Check that production now carries the welcome message:

bash
sky state public show --project tutorial-app --env production

The output should show the welcomeText value from staging. To see the SDK read it, run a production build, or set VITE_SKYSTATE_ENV=production in .env.local and restart the dev server. The app shows the production welcome text.

If your app includes the user-state parts of the tutorial, sign in on the production URL too. The callback URL from Step 3 is what lets SkyState return to the production app after sign-in.

Two more paths worth seeing.

--yes skips the prompt, for CI that has no terminal to answer it:

bash
sky state public promote \
  --project tutorial-app \
  --from staging \
  --to production \
  --keys welcomeText \
  --yes \
  --comment "CI: promote welcome text to production"

If two promotions hit the same target at once, the server rejects the second with 412, and the CLI exits with code 1 and prints Conflict: production was updated while you were editing. Run sky state public show --project tutorial-app --env production to see the current state, then promote again.

What you learned ​

  • The provider takes its environment from a build variable, so development, staging, and production builds each reach their own state.
  • User-state sign-in needs end-user auth enabled once per project, and a callback URL per deployed environment.
  • A promotion always follows the same path: preview with --dry-run, apply at the prompt, then check.
  • --keys narrows a promotion to specific top-level keys, so you ship one key at a time and leave other production values alone.
  • --yes stands in for the confirmation a CI pipeline cannot give.

Where to go next ​