Search code examples
typescriptpaymentcheckoutsveltekitpaddle-paddle

How to use Paddle with SvelteKit?


I'm trying to display a Paddle Inline Checkout in SvelteKit. However I always get Name Paddle not found as an error. I'm unable to use all the script at all.

Console Error:

Uncaught (in promise) ReferenceError: Paddle is not defined
   instance Checkout.svelte:7
   init index.mjs:2016
   Checkout Checkout.svelte:110
   createProxiedComponent svelte-hooks.js:341
   ProxyComponent proxy.js:242
   Proxy<Checkout> proxy.js:349
   create_fragment +page.svelte:58
   init index.mjs:2031
   Page +page.svelte:242
   createProxiedComponent svelte-hooks.js:341
   ProxyComponent proxy.js:242
   Proxy<+page> proxy.js:349
   construct_svelte_component_dev index.mjs:2232
   update root.svelte:274
   update_slot_base index.mjs:100
   update layout.svelte:40
   update index.mjs:1209
   flush index.mjs:1169
   promise callback*schedule_update index.mjs:1120
   make_dirty index.mjs:1984
   ctx index.mjs:2022
   $$set root.svelte:581
   get proxy.js:83
   $set index.mjs:2123
   key proxy.js:46
   update client.js:321
   navigate client.js:1094
   goto client.js:183
   goto client.js:1266
   routeToPage navigation.ts:4
   prepNewService SearchBar.svelte:17
   searchDB SearchBar.svelte:8
   click_handler SearchBar.svelte:25
   listen index.mjs:417
   listen_dev index.mjs:2174
   mount SearchBar.svelte:84
   m svelte-hooks.js:291
   mount_component index.mjs:1949
   mount +page.svelte:112
   m svelte-hooks.js:291
   mount_component index.mjs:1949
   update root.svelte:277
   update_slot_base index.mjs:100
   update layout.svelte:40
   update index.mjs:1209
   flush index.mjs:1169
   promise callback*schedule_update index.mjs:1120
   make_dirty index.mjs:1984
   ctx index.mjs:2022
   $$set root.svelte:581
   get proxy.js:83
   $set index.mjs:2123
   key proxy.js:46
   update client.js:321
   navigate client.js:1094
   _start_router client.js:1536
   _start_router client.js:1528
   start start.js:42
   async* new-service:20

My component looks like this:

<svelte:head>
        <script src="https://cdn.paddle.com/paddle/paddle.js"></script>
</svelte:head>

<script type="text/javascript" lang="js">
    Paddle.Setup({ vendor: 00000 });
    Paddle.Environment.set('sandbox');
    Paddle.Checkout.open({
        method: 'inline', // set to `inline`
        product: 12345, // replace with a product ID or plan ID
        allowQuantity: true,
        disableLogout: true,
        frameTarget: 'iframe', // className of your checkout <div>
        frameInitialHeight: 450, // `450` or above
        frameStyle: 'width:100%; min-width:312px; background-color: transparent; border: none;' });
</script>

<div id="iframe"></div>

I also tried to place the script tag in the app.html body and head tag. Adding async to the script also didn't do anything.

I don't know if it's important but I'm using typescript for the whole project, except here.


Solution

  • As mentioned in the comments, it's a timing problem. When the code is executed, the browser is not done loading the script from the cdn, parsing its content and setting up the Paddle class. Executing this in the onMount hook might solve it, and also makes sure that it is executed in client context only, but not on serverside.

    Also, like the author of this question found out himself, it seems you need to use a class instead of an id.