Dev & Publish
Run a theme locally in preview mode, then publish it for review.
Local Development
Run the theme with its own dev server. Because the review sandbox renders your theme where the ThreeU API is unreachable, every theme needs a preview (demo) mode: when there is no public token / real brand, hand <ThemeProvider> a demo brand and a demo storefront client. The data hooks call useStorefront(), which throws without a client — a plain "no data" fallback is not enough.
# .env.local
VITE_THREEU_PREVIEW=true
# terminal
npm run devPreview Mode Skeleton
A duck-typed demo client only needs the methods the hooks call — catalog.list/get/getBySlug, collections.list, delivery.methods/quote, payments.methods, coupons.validate, leads.create, bookings.create, content.faqs/blogPost, and top-level checkout(). createMockFetch from threeu-sdk/testing can back a real ThreeuStorefront instead.
import { ThemeProvider } from "threeu-sdk/theme";
import { demoBrand, demoStorefront } from "./demo";
const preview = import.meta.env.VITE_THREEU_PREVIEW === "true";
export function ThemeRoot({ children }) {
return preview
? <ThemeProvider brand={demoBrand} storefront={demoStorefront} preview>{children}</ThemeProvider>
: <ThemeProvider brand={brand} storefront={storefront}>{children}</ThemeProvider>;
}Publishing
Publishing uploads a bundle and creates a submission that ThreeU reviews. It does not make the theme live.
npm run build # → preview-dist/index.html
TOKEN=$(grep '^THREEU_DEVELOPER_TOKEN=' .env.threeu | cut -d= -f2-)
export THREEU_DEVELOPER_TOKEN="$TOKEN"
npx threeu publish --dry-run # validate + bundle, no upload
npx threeu publishWhat the CLI Does
- Detects the project from
threeu.json(kind, key, name, version, manifest). - Bundles a tar.gz — excludes
node_modules,dist,.git,.env*and other generated/sensitive files; includes `preview-dist/`. Cap: 50 MB after exclusions. POST /api/developer/publish/init— checks the account is active, the key is not owned by another developer, and your per-account project limit; returns a presigned upload URL (15 min).- Uploads the bundle to ThreeU's private bucket.
POST /api/developer/publish/{id}/complete— verifies the object and size, sets the submission touploaded, queues review.
Submission lifecycle: pending_upload → uploaded → approved | rejected. Approved themes are then integrated into the storefront by ThreeU (see [Publishing Themes](/docs/themes-publishing)).
Verify a Submission
Find your submission by kind + project_key; status uploaded means it is in the review queue. Each publish creates a new submission — to fix a failed check, correct the project and publish again.
curl -s -H "Authorization: Bearer $TOKEN" https://api.threeu.app/api/developer/submissionsToken Safety
- Name the secret file `.env.threeu`, not
.threeu.env— the bundler excludes.env*, so a file starting with.threeuwould be uploaded with your token. - The token contains a
|. Do notsourcethe env file (the shell reads|as a pipe); read it withgrep … | cut -d= -f2-as above. - After a dry run, prove the bundle is clean:
tar tzf <bundle> | grep -iE '\.env|token'must print nothing. - Validate the token before publishing:
GET https://api.threeu.app/api/developer/mewith the bearer token →200. Sandbox uses a separate database — a production token returns401there.
Never commit the token
If a token ever lands in a bundle or a commit, rotate it in the Developer Console.