Deployment — managed (Wix CLI release)
For a managed project, Wix owns the hosting, so finalizing the live site is a single command — Wix handles publishing the site and registering the deployed origin on the OAuth app out of the box. There are no manual publish or origin-registration calls (unlike the self-hosted types).
Release
From the project directory:
CI=1 npx @wix/cli@latest release- Publishes whatever the managed project is configured to deploy to Wix's hosting/CDN, and brings the live site up.
- The deployed origin is registered on the OAuth app automatically — the frontend's visitor SDK calls are accepted from the live URL with no extra step.
- The published URL is printed on stdout (
Site published on <url>).
Give the user both links — the live site and the dashboard
When you close the run, surface two links, not one:
- The live site URL — the
Site published on <url>value from release above. - The site dashboard (Business Manager) —
https://manage.wix.com/dashboard/<SITE_ID>, where<SITE_ID>is thesiteIdheld in scratch (read fromwix.config.json). This is where the owner manages the site behind the headless frontend — view store orders, edit content, manage members, etc. Always include it: a headless site has no editor button, so without this link the owner has no obvious way back into their own backend, and the seeded content/apps look unreachable.
Present them plainly, e.g.:
Live site: <published-url>
Dashboard: https://manage.wix.com/dashboard/<SITE_ID>Suggest a custom domain (required, after release)
The published URL is a generic Wix subdomain, so a custom domain is the obvious next step and the CLI handles the whole flow. Run step 1 on every managed release and put its result in the same message as the links above — this is a step you execute, not a judgment call about whether the user seems interested. It applies in a non-interactive run too: there's no one to ask, so just include the suggestions and a checkout link in your final message and let the user act on them.
Run the suggestion command. Build a search query from what you know about the site — its business name, topic, or purpose from this run (not a generic placeholder):
npx @wix/cli@latest account domain suggest "<business name or site topic>" --limit 5 --jsonAll returned suggestions are already available for purchase. Name a few of the best fits in your message, and mention they can explore more options — re-run
suggestwith different keywords, a higher--limit, or--tld com net ...to filter extensions.Give a checkout link. Generate a site-scoped deep link for the domain the user picks — or, if nobody is there to pick, for the best of the suggestions — so the purchase is tied to this site and can be connected after payment:
npx @wix/cli@latest account --site-id <SITE_ID> domain checkout-link <domain> --jsonUse the
siteIdfromwix.config.json.checkout-linkonly returns a site-scoped checkout URL; it does not purchase a domain or charge the user. The user completes payment in the browser.Your site is live at <published-url>, and you can manage it from your dashboard. To build a professional online presence, connect a custom domain — mybusiness.com is available.
Once the suggestions and the link are in front of the user, you're done: if they don't want a domain, drop it — one offer, no upselling.
Before you sign off — feedback checkpoint
This is the last step of the run — the natural point to check ../FEEDBACK.md. Don't wait for the
user to complain: run a quick self-check over the whole session (not just this final step) — a
confusing API response, a doc that was wrong/missing, an extra retry, a workaround you had to invent,
anything that cost more turns than it should have. If anything qualifies, offer to relay it to Wix
as you deliver the links above; send only after an explicit yes.
Member login on a non-Astro frontend — register the callback URI (post-release)
Only when the run has member login on a non-Astro SPA/static frontend using the Wix login page (inline-recipes/how-to-code-members-non-astro.md — the getAuthUrl → /callback handshake). Astro's built-in /api/auth/* callback shapes are auto-registered; a non-Astro SPA's own callback path is not — and login stays dead (4xx on the login redirect) until you register it. This is a genuine gap wix release does not close for you.
releaseauto-registers the deployed origin (allowedRedirectDomains) — that's the visitor-SDK/CORS surface (above). It does not register the member-login callback URL (allowedRedirectUris). These are two different fields; members needs both, and only the first is automatic.- This is a post-release step — the callback URL embeds the deployed origin, which is unknown until
releaseprints it. Do it right after release, once the URL is known. - ⚠️
allowedRedirectUrisIS writable via the API — do not conclude it's read-only/dashboard-only. TheUpdateOAuthAppreference may not list it among the obvious updatable fields, but a maskedPATCHsets it. The trap is a required field mask: withoutmask.pathsthePATCHreturns200and silently no-ops.
ID="<clientId>" # the OAuth app id == the public clientId
# 1) GET first and append — the PATCH REPLACES the array, so include what's already there:
curl -sS -w "\nHTTP_STATUS:%{http_code}" https://www.wixapis.com/oauth-app/v1/oauth-apps/$ID \
-H "Authorization: Bearer $TOKEN"
# 2) PATCH with the field mask (register BOTH the exact callback and the versioned-preview wildcard):
curl -sS -X PATCH https://www.wixapis.com/oauth-app/v1/oauth-apps/$ID \
-H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-w "\nHTTP_STATUS:%{http_code}" -d '{
"oAuthApp": { "id": "'"$ID"'",
"allowedRedirectUris": [ <existing…>, "https://<host>/callback", "https://*-<host>/callback" ] },
"mask": { "paths": ["allowedRedirectUris"] }
}'- Include both the exact URL and the
https://*-<host>/…wildcard — Wix serves versioned preview subdomains. The callback path must match the recipe'sredirectUriexactly (e.g.window.location.origin + '/callback'). allowedRedirectDomainsandallowedRedirectUriscan go in onePATCH(list both undermask.paths) if you ever need to set the origin by hand too.- If you're not the one deploying, you can't know the domain — flag the member-login callback URI to the user to register, and note login is dead until they do (higher-stakes than the origin flag).
Custom-login (
how-to-code-members-custom-login.md) does not need this —register/loginare direct API calls with no login-page redirect. OnlysendPasswordResetEmail'sredirectUriand logout's return URL need allow-listing there.
Static frontends (no build step)
These two fixes are Wix-hosting facts — they apply to a connected static site (plain HTML, no bundler) on the managed path, and the docs are silent on both. A bundler SPA that builds to its own output directory doesn't need them.
- The entry file must be named
index.html. Wix servesindex.htmlat the site root. A brought-in design named anything else (e.g."My Design.html") publishes "successfully" but 500s/404s at runtime. Rename the entry toindex.htmlbefore release and fix internal references to it. site.outputDirectorymust point at the directory holdingindex.html.initwritessite.outputDirectory: "./dist", which assumes an SPA that builds todist. A static site has no build, so./distis wrong — setoutputDirectoryinwix.config.jsonto the directory that actually containsindex.html, orreleasepublishes but the live site 404s at root.
Transient errors
A release can hit transient infrastructure errors (ECONNRESET, ETIMEDOUT, STATE_MISMATCH, "try again shortly"). Retry the release serially up to 3× with a short backoff. Build failures are not retryable — they're code bugs; fix the code, not the retry.
That's the whole of finalize for managed — no site-publisher call, and no oauth-app origin PATCH (the origin is auto-registered). The one exception is the member-login callback on a non-Astro frontend above — that allowedRedirectUris PATCH is manual and required.