Translations and monetization get safer defaults: scoped publishing, free layout sync, hand-editable variants, discount codes, org-wide products, and readiness warnings when checkout would fail.
What we shipped
Two areas that kept surfacing as "it looks broken" got structural fixes — not more UI band-aids.
Translations
Scoped publishing — the main Publish menu covers the default locale only. Translation variants publish from the Translations tab, with per-language re-publish counts when a variant goes dirty after going live.
Layout vs text staleness — Layout out of date is fixed with a free Update layout action that keeps your translated wording. Text changed still needs a translator.
Hand edits — fix AI wording directly in the editor; saving marks the variant Reviewed, and re-translate confirms name how many hand-corrected pages would be overwritten.
Page titles — if the metadata batch fails, bodies stay translated and you get Translate the titles instead of silent "Untitled" SEO.
Locale folders — collection labels and paywall gates on translated paths stay in sync with the source tree.
Monetization
Discount codes — create codes under Monetization, buyers apply them on the paywall before checkout, and the server prices what Stripe charges.
Org-wide products — sell one offer across every site in the organization; one purchase unlocks everywhere.
Readiness card — surfaces Stripe/payout gaps, active products without prices, and paywalls pointing at unsellable products. Hidden when nothing is wrong.
Recurring is Stripe-only — the product editor blocks subscriptions when card payments are not connected, instead of failing at checkout.
Under the hood (no action needed)
npm run selftest and CI now gate translation, gating, checkout metadata, and discount-code invariants.
POST /api/v1/sites/{siteId}/publish accepts optional locale_scope (default, all, or a locale list). Omitted means default locale only.
Apply migrations translation_metadata_pending, translation_structure_sync, discount_code_redemption, and products_org_scope before deploying. Existing multilingual sites: npm run backfill-locale-folders.