Skip to content

Stripe: allow selecting the Stripe.js SDK version (acacia / basil / clover / dahlia / …)Β #796

Description

@williamchong

πŸ†’ Your use case

Stripe now ships pinned, versioned builds of Stripe.js (https://docs.stripe.com/sdks/stripejs-versioning), loaded from https://js.stripe.com/{version}/stripe.js (e.g. acacia, basil, dahlia, …), alongside the evergreen https://js.stripe.com/v3/stripe.js. Pinning a version lets teams adopt Stripe.js changes deliberately instead of being moved onto new behavior automatically.

Right now useScriptStripe() hard-codes the loader URL to https://js.stripe.com/basil/stripe.js (packages/script/src/runtime/registry/stripe.ts), with no way to override it.
When I do

const{ onLoaded }=useScriptStripe()

I would expect to be able to choose which Stripe.js version is injected β€” e.g. pin to a known-good release for stability, or move to a newer one when I'm ready β€” without ejecting from the registry script and calling useScript by hand.

πŸ†• The solution you'd like

Add an optional version field to StripeOptions and use it to build the loader URL, mirroring the existing Google Maps v option (union([literal(...), …, string()]), injected into the src).

// schemas.tsexportconstStripeOptions=object({advancedFraudSignals: optional(boolean()),/** * The Stripe.js SDK version to load. * Named releases get autocomplete; any future code is also accepted. * @default 'basil' // (or 'v3' β€” see open question below) * @see https://docs.stripe.com/sdks/stripejs-versioning */version: optional(union([literal('v3'),literal('acacia'),literal('clover'),literal('dahlia'),string(),])),})
// stripe.tsconstversion=options?.version||'basil'// ...src: withQuery(`https://js.stripe.com/${version}/stripe.js`,(typeofoptions?.advancedFraudSignals==='boolean'&&!options?.advancedFraudSignals)
? {advancedFraudSignals: false}
: {},),

Usage, both via the composable and the Nuxt config registry (the latter works automatically because the registry config is derived from StripeOptions):

// composableconst{ onLoaded }=useScriptStripe({version: 'acacia'})
// nuxt.configexportdefaultdefineNuxtConfig({scripts: {registry: {stripe: {version: 'acacia'}}}})

πŸ” Alternatives you've considered

  • Eject to useScript and load https://js.stripe.com/<version>/stripe.js manually β€” works, but loses the typed registry integration, advancedFraudSignals handling, and config-level setup that useScriptStripe() provides.
  • Keep hard-coding the version in the registry and bump it on each release β€” this is the status quo; it forces a package release for what is really a per-app preference.

ℹ️ Additional info

  • Precedent: this is essentially the existing Google Maps v option (schemas.ts), so the validation/URL-injection pattern is already established and accepted in the codebase.
  • Open question β€” default value: the loader is currently pinned to basil. Keeping basil as the default is fully backward-compatible; defaulting to the evergreen v3 is more future-proof but Stripe notes "v3 is no longer recommended for integrations" (still supported). Happy to go with whichever the maintainers prefer β€” flagging it because it's the one behavior-affecting choice here.
  • Scope: this is about the Stripe.js SDK version (the loader URL), which is distinct from the API version passed to Stripe(key, { apiVersion }). The
    ScriptStripePricingTable component loads js.stripe.com/v3/pricing-table.js separately and would be left as-is (pinned pricing-table.js builds may not exist).
  • Implementation touches packages/script/src/runtime/registry/{stripe.ts,schemas.ts}; pnpm generate:types should be re-run afterward.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions