{"id":12586,"library":"vue-stripe-js","title":"Vue Stripe.js Integration","description":"vue-stripe-js (current stable version 2.0.2) is a library that provides Vue 3 components for integrating Stripe.js into web applications, enabling developers to build various payment UIs. It maintains an active release cadence with frequent minor updates for bug fixes and compatibility, including enhanced Nuxt 3 support. Major versions, like v2.0.0, introduce significant architectural shifts such as the transition to ES modules. The library's core philosophy emphasizes minimal abstractions, offering direct control over Stripe.js functionalities while leveraging Vue's reactivity system. It is fully TypeScript-ready and designed to work seamlessly with modern frontend toolchains, acting as a lightweight, unopinionated bridge between the Stripe.js SDK and the Vue component lifecycle for creating advanced payment integrations.","status":"active","version":"2.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/ectoflow/vue-stripe-js","tags":["javascript","Vue","Stripe","Elements","Checkout","Payments","typescript"],"install":[{"cmd":"npm install vue-stripe-js","lang":"bash","label":"npm"},{"cmd":"yarn add vue-stripe-js","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-stripe-js","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for loading Stripe.js and accessing its core functionalities. It is a peer dependency.","package":"@stripe/stripe-js","optional":false}],"imports":[{"note":"This is the primary way to load Stripe.js programmatically. Remember to install `@stripe/stripe-js` alongside `vue-stripe-js`.","wrong":"const loadStripe = require('@stripe/stripe-js').loadStripe","symbol":"loadStripe","correct":"import { loadStripe, type Stripe } from '@stripe/stripe-js'"},{"note":"Since v2.0.0, `vue-stripe-js` is ESM-only. CommonJS `require()` is no longer supported and will cause errors.","wrong":"const StripeElements = require('vue-stripe-js').StripeElements","symbol":"StripeElements","correct":"import { StripeElements } from 'vue-stripe-js'"},{"note":"StripeElement is a named export. Attempting a default import will fail.","wrong":"import StripeElement from 'vue-stripe-js'","symbol":"StripeElement","correct":"import { StripeElement } from 'vue-stripe-js'"},{"note":"Type imports are crucial for TypeScript projects and should be imported from `@stripe/stripe-js`.","symbol":"StripeElementsOptionsMode","correct":"import type { StripeElementsOptionsMode } from '@stripe/stripe-js'"}],"quickstart":{"code":"<template>\n  <form\n    v-if=\"stripeLoaded\"\n    @submit.prevent=\"handleSubmit\"\n  >\n    <StripeElements\n      :stripe-key=\"publishableKey\"\n      :instance-options=\"stripeOptions\"\n      :elements-options=\"elementsOptions\"\n      ref=\"elementsComponent\"\n    >\n      <StripeElement\n        type=\"payment\"\n        :options=\"paymentElementOptions\"\n        ref=\"paymentComponent\"\n      />\n    </StripeElements>\n    <button type=\"submit\">\n      Submit Payment\n    </button>\n  </form>\n  <div v-else>Loading Stripe...</div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onBeforeMount, ref } from \"vue\"\nimport { loadStripe } from \"@stripe/stripe-js\"\nimport { StripeElements, StripeElement } from \"vue-stripe-js\"\n\nimport type {\n  StripeElementsOptionsMode,\n  StripePaymentElementOptions,\n} from \"@stripe/stripe-js\"\n\n// Use your actual publishable key from Stripe Dashboard\nconst publishableKey = process.env.VITE_STRIPE_PUBLISHABLE_KEY ?? \"pk_test_YOUR_KEY\";\n\nconst stripeOptions = ref({\n  // Optional: https://stripe.com/docs/js/initializing#init_stripe_js-options\n})\nconst elementsOptions = ref<StripeElementsOptionsMode>({\n  // Required: https://stripe.com/docs/js/elements_object/create#stripe_elements-options\n  mode: \"payment\",\n  amount: 1099, // Example: $10.99\n  currency: \"usd\",\n  appearance: {\n    theme: \"flat\",\n  },\n})\nconst paymentElementOptions = ref<StripePaymentElementOptions>({\n  // Optional: https://docs.stripe.com/js/elements_object/create_payment_element#payment_element_create-options\n})\nconst stripeLoaded = ref(false)\nconst clientSecret = ref(\"\") // This should come from your backend\n\nconst elementsComponent = ref<typeof StripeElements | null>(null)\nconst paymentComponent = ref<typeof StripeElement | null>(null)\n\nonBeforeMount(async () => {\n  try {\n    await loadStripe(publishableKey);\n    stripeLoaded.value = true;\n\n    // In a real application, you would call your backend here\n    // to create a PaymentIntent and fetch its client_secret.\n    // For this example, we'll simulate a client_secret.\n    clientSecret.value = \"pi_FAKE_CLIENT_SECRET_TEST\"; // Replace with actual client_secret\n    elementsOptions.value.clientSecret = clientSecret.value; // Assign clientSecret to elementsOptions\n  } catch (error) {\n    console.error(\"Failed to load Stripe.js or initialize elements:\", error);\n  }\n})\n\nasync function handleSubmit() {\n  if (!elementsComponent.value || !paymentComponent.value || !clientSecret.value) {\n    console.error(\"Stripe elements not ready or client secret missing.\");\n    return;\n  }\n\n  const stripeInstance = elementsComponent.value.instance;\n  const elements = elementsComponent.value.elements;\n\n  if (!stripeInstance || !elements) {\n    console.error(\"Stripe or Elements instance not available.\");\n    return;\n  }\n\n  console.log(\"Attempting to confirm payment...\");\n  const { error } = await stripeInstance.confirmPayment({\n    elements,\n    confirmParams: {\n      return_url: window.location.origin + '/payment-complete',\n    },\n  });\n\n  if (error) {\n    console.error(\"Payment confirmation failed:\", error.message);\n    // Display error to the user\n  } else {\n    console.log(\"Payment successful! Redirecting to return_url.\");\n    // User will be redirected to return_url\n  }\n}\n</script>","lang":"typescript","description":"This quickstart demonstrates how to load Stripe.js, initialize StripeElements and StripeElement components for a Payment Element, and handle a form submission to confirm a payment intent in a Vue 3 TypeScript application."},"warnings":[{"fix":"Ensure all imports for `vue-stripe-js` and its dependencies use `import ... from '...'` syntax. Projects using older bundlers or Node.js versions that do not fully support ESM may need configuration adjustments or an upgrade.","message":"Version 2.0.0 of `vue-stripe-js` transitioned to be ESM-only (ES Modules). CommonJS `require()` syntax is no longer supported and will cause runtime errors.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Run `npm install @stripe/stripe-js` or `yarn add @stripe/stripe-js` to ensure the core Stripe.js library is available.","message":"The `@stripe/stripe-js` package is a peer dependency and must be explicitly installed alongside `vue-stripe-js`. Failing to do so will result in module resolution errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use `onBeforeMount` and `loadStripe` to asynchronously load Stripe.js, or ensure the Stripe.js script tag (`<script src=\"https://js.stripe.com/v3/\"></script>`) is present and loaded before your Vue application mounts.","message":"Stripe.js must be loaded and available in the global scope (or via `loadStripe`) *before* `vue-stripe-js` components are mounted. Attempting to render Stripe components without Stripe.js loaded will lead to runtime errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Implement a server-side endpoint that creates a PaymentIntent/SetupIntent and returns its `client_secret` to your frontend application. Pass this `client_secret` to the `elementsOptions` of `StripeElements`.","message":"The `client_secret` for a PaymentIntent or SetupIntent must be obtained from your backend server. It should never be hardcoded or generated purely on the client-side, as this would expose your secret key.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"`npm install @stripe/stripe-js` or `yarn add @stripe/stripe-js`","cause":"The `@stripe/stripe-js` package is a peer dependency of `vue-stripe-js` and was not installed.","error":"Failed to resolve import \"@stripe/stripe-js\" from \"...\" (e.g., in Vite build)"},{"fix":"Ensure your project uses `import ... from '...'` statements for `vue-stripe-js` and configure your build system (e.g., `package.json` `\"type\": \"module\"`) to handle ES Modules correctly. Review the v2.0.0 upgrade guide.","cause":"`vue-stripe-js` was imported using CommonJS `require()` syntax in an environment configured for ES Modules, or vice-versa, specifically after the v2.0.0 breaking change to ESM-only.","error":"SyntaxError: Cannot use import statement outside a module"},{"fix":"Ensure that `stripeLoaded.value` is `true` and the component refs (`elementsComponent.value`, `paymentComponent.value`) are populated before attempting to access their properties or methods, typically within an `async`/`await` block after `loadStripe` completes or inside an event handler.","cause":"A component ref (e.g., `elementsComponent.value?.instance`) is being accessed before the component is fully mounted or before Stripe.js has finished loading and initialized the instance.","error":"Property \"instance\" was accessed during render but is not defined on instance."},{"fix":"Ensure `loadStripe()` is called and awaited before mounting Stripe components, or include `<script src=\"https://js.stripe.com/v3/\"></script>` in your `index.html` `<body>` and verify it loads successfully before Vue application initialization.","cause":"The Stripe.js library (from `js.stripe.com/v3/`) has not been loaded into the page's global scope before `loadStripe` is called or Stripe components attempt to initialize.","error":"ReferenceError: Stripe is not defined"}],"ecosystem":"npm"}