Add catalog overrides for offer accept and decline CTAs#36
Merged
Conversation
Customer report: the rebate accept button ("Accept refund") had no
override path anywhere — offer cta/declineCta are synthesized
server-side defaults, the flow builder has no CTA fields, and the
chrome catalog deliberately excluded offer copy. The embed's rebateAccept
key covered exactly this.
New offer.acceptCta.<type> keys and a shared offer.declineCta, all with
empty defaults: a set value replaces the offer's copy, an unset key
falls through — so when authored per-offer CTAs exist someday, they
keep winning over unset keys. Rides the existing override pipeline, so
the dashboard rows and org-level delivery come for free.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Customer report (Slack, matt.mckenney): overriding the rebate button text had no path —
offer.copy.cta/declineCtaare server-synthesized defaults (step-normalizer.ts), the flow builder has no CTA fields, and the chrome catalog deliberately excluded offer copy. The embed'srebateAcceptkey covered exactly this case.Design docs: Phase 2 implementation overview
What
New chrome keys, all with empty defaults:
offer.acceptCta.{discount,pause,trial_extension,plan_change,contact,redirect,rebate}offer.declineCta(shared across types)Default components render
catalogValue || offer.copy.cta— a set key wins, an unset key falls through to the offer's copy. Since every CTA today is synthesized, this is behavior-neutral until someone sets a key; and when authored per-offer CTAs land later (builder fields), they keep winning over unset keys, so precedence stays coherent: authored copy → catalog override → synthesized default.Rides the whole existing pipeline: org dashboard rows generate automatically from the catalog mirror (monorepo PR to follow),
sdkTranslationsdelivery already handles the new keys, per-language works.Testing
Override + fallthrough covered against the rendered rebate flow. 222 tests, tsc + biome clean.