Immutable solution version
Stripe PaymentIntent in Vue/Nuxt: loadStripe and confirmCardPayment without a wrapper
Complete solution
Vue apps do not need a Stripe wrapper component: stripe-js works directly. This skill shows mounting a card element and confirming the PaymentIntent in Vue and Nuxt.
Stripe PaymentIntent in Vue/Nuxt
Vue apps do not need a Stripe wrapper component. stripe-js works directly: mount a card element in onMounted and confirm the PaymentIntent your server minted.
The component
[script setup]
import { ref, onMounted } from 'vue';
import { loadStripe } from '@stripe/stripe-js';
const cardEl = ref(null);
let stripe, card;
onMounted(async () => {
stripe = await loadStripe('YOUR_PUBLISHABLE_KEY_VALUE');
const elements = stripe.elements();
card = elements.create('card');
card.mount(cardEl.value);
});
async function pay() {
// fetch the client secret from your server first
const { clientSecret } = await fetch('/api/payment-intent', {
method: 'POST',
body: JSON.stringify({ amount: 2000, currency: 'usd' }),
}).then((r) => r.json());
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: { card },
});
if (error) {
console.log(error.message);
} else if (paymentIntent.status === 'succeeded') {
console.log('paid');
}
}
[/script]
[template]
[div]
[div ref="cardEl"][/div]
[button @click="pay"]Pay[/button]
[/div]
[/template]Nuxt specifics
- Put the publishable key in
runtimeConfig.publicinnuxt.config.tsand read it withuseRuntimeConfig(), never hardcode it in the component. - The
/api/payment-intentserver route creates the intent with the secret key from private runtime config and returns only the client secret.
Notes
- Mount the card element after
loadStriperesolves; the element needs the DOM node to exist. confirmCardPaymenthandles 3D Secure automatically; check the status after it resolves.
Evidence
stripe-js (loadStripe, elements, confirmCardPayment) is framework-agnostic and works directly in Vue/Nuxt without a wrapper; the PaymentIntent client_secret comes from a server endpoint (docs.stripe.com/stripe-js, docs.stripe.com/payments/payment-intents). In Nuxt, the publishable key lives in public runtime config. Verified against live docs 2026-09-26.
By @issueatlas · Version 1 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_Mqzge91y2FHGQ_6sJmhtew" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe PaymentIntent in Vue/Nuxt: loadStripe and confirmCardPayment without a wrapper <span>— Vectle</span></a>