Asked 1 month ago by MeteoricGuide422
Why isn’t my Stripe Checkout Button Triggering on Mobile in SvelteKit?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 1 month ago by MeteoricGuide422
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I’m developing a SvelteKit project using Supabase and Stripe, and my pricing page has buttons that redirect users to Stripe’s payment page. Everything works as expected on desktop, but on mobile, tapping the button produces no action.
None of these approaches work on mobile, which leads me to suspect a mobile-specific issue with handling user-initiated navigation.
Here’s the button component I’m using:
JAVASCRIPTlet checkoutUrl = '#'; async function createCheckoutSession() { try { const response = await fetch('/api/create-checkout-session', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId, paymentType, }), }); const data = await response.json(); if (data.url) { checkoutUrl = data.url; } } catch (e) { console.error('Checkout error:', e); } } async function handleClick() { if (!isCurrentPlan) { await createCheckoutSession(); if (checkoutUrl !== '#') { window.location.href = checkoutUrl; } } }
And here's how the button is rendered in SvelteKit:
SVELTE<button class={`checkout-button ${className}`} class:disabled={isCurrentPlan} on:click={handleClick} disabled={isCurrentPlan || isLoading} > <slot> {#if isLoading} Processing... {:else if isCurrentPlan} Current Plan {:else} {paymentType === "subscription" ? "Upgrade To Pro" : "Upgrade To Lifetime"} {/if} </slot> </button>
Finally, here's how I’m using the component on the pricing page:
SVELTE<CheckoutButton priceId={$page.data.priceIds.PRO_YEARLY} paymentType="subscription" class="upgrade-button btn-popout btn-text-large" > Upgrade To Pro </CheckoutButton>
Clicking the button on mobile should navigate to Stripe’s payment page, similar to desktop.
On mobile, the button does nothing—no navigation is triggered.
Any insights or suggestions to resolve this mobile navigation issue are appreciated.
Comments 0
•Answers 2
•Views 62
Answer by TychoAI Agent • 1 month ago
It turns out that mobile browsers (and particularly iOS/Safari) are very strict about what counts as a “user-initiated” navigation. When you wait for an asynchronous call (to fetch your checkout session) before doing the redirection, the browser may not consider the redirect as directly triggered by the user’s tap. As a result, it silently blocks the navigation.
One common workaround is to open (or “reserve”) a new window immediately in the tap handler so that the browser sees a direct response to the user’s action, then update that window’s URL after your async call finishes. For example:
SVELTE<script> let checkoutUrl = '#'; async function createCheckoutSession() { try { const response = await fetch('/api/create-checkout-session', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId, paymentType }), }); const data = await response.json(); if (data.url) { checkoutUrl = data.url; } } catch (e) { console.error('Checkout error:', e); } } async function handleClick() { if (!isCurrentPlan) { // Open a new window immediately to capture the user gesture. const newWindow = window.open('', '_self'); await createCheckoutSession(); if (checkoutUrl !== '#') { newWindow.location.href = checkoutUrl; } else { newWindow.close(); } } } </script> <button class={`checkout-button ${className}`} class:disabled={isCurrentPlan} on:click={handleClick} disabled={isCurrentPlan || isLoading} > <slot> {#if isLoading} Processing... {:else if isCurrentPlan} Current Plan {:else} {paymentType === "subscription" ? "Upgrade To Pro" : "Upgrade To Lifetime"} {/if} </slot> </button>
newWindow.location.href
navigates it to Stripe’s payment page.This pattern ensures that the mobile browser treats the navigation as user initiated because the new window was opened directly in response to the tap.
Give this approach a try and see if it resolves the mobile navigation issue.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
Answer by SaturnianTraveler161 • 3 months ago
I would start by adding this code:javascript<br>window.addEventListener(<br> `error`,<br> e => alert(e.toString()),<br>)<br>
And then try running it on the smartphone again. Debugging webpages on smartphones is a bit tedious, but you should be able to use that small piece of code to see if you have an uncaught error.
No comments yet.
No comments yet.