在SvelteKit中集成Paddle内联结账遇Paddle未定义问题求助
解决SvelteKit中「Paddle is not defined」错误
核心原因
Paddle脚本加载时机与组件执行时机不匹配,异步加载的脚本未完成初始化时,组件就尝试调用Paddle全局对象;同时SSR(服务器端渲染)环境下window不存在也会触发同类报错。
可行解决方案
1. 组件内动态加载并等待脚本就绪
直接在Checkout.svelte中控制脚本加载流程,确保Paddle初始化后再调用相关方法:
import { onMount } from 'svelte'; let Paddle; async function loadAndInitPaddle() { if (typeof window === 'undefined') return; if (!window.Paddle) { // 动态创建脚本标签 const script = document.createElement('script'); script.src = 'https://cdn.paddle.com/paddle/v2/paddle.js'; // 等待脚本加载完成 await new Promise((resolve, reject) => { script.onload = resolve; script.onerror = () => reject(new Error('Paddle脚本加载失败')); document.body.appendChild(script); }); } Paddle = window.Paddle; // 初始化Paddle(替换为你的商家ID) Paddle.Setup({ vendor: 123456 }); } onMount(async () => { await loadAndInitPaddle(); // 这里安全调用Paddle结账方法,例如: // Paddle.Checkout.open({ product: 'prod_xxx' }); });
2. 处理TypeScript全局类型提示
由于项目使用TypeScript,即使组件用JS,也需要声明全局Paddle类型避免类型报错。在项目根目录创建src/global.d.ts文件:
declare interface Window { Paddle: { Setup: (config: { vendor: number }) => void; Checkout: { open: (options: any) => void; }; // 按需补充其他Paddle API类型 }; }
3. 修正app.html中脚本的加载方式
如果坚持在app.html中引入脚本,需去掉async/defer属性,或添加加载完成标记确保组件等待脚本就绪:
在app.html的</body>前添加:
<script src="https://cdn.paddle.com/paddle/v2/paddle.js" onload="window.paddleReady = true"></script>
然后在Checkout.svelte中:
import { onMount } from 'svelte'; onMount(async () => { // 等待脚本加载完成 while (!window.paddleReady) { await new Promise(resolve => setTimeout(resolve, 100)); } // 初始化并使用Paddle window.Paddle.Setup({ vendor: 123456 }); });
4. 确保代码仅在客户端执行
SvelteKit默认启用SSR,服务器端没有window对象,必须用browser判断或onMount钩子限制代码在客户端运行:
import { browser } from '$app/environment'; import { onMount } from 'svelte'; // 方式1:用browser判断 if (browser) { // 这里编写Paddle相关代码 } // 方式2:用onMount(仅客户端执行) onMount(() => { // 这里编写Paddle相关代码 });
内容的提问来源于stack exchange,提问作者Flajt
相关产品推荐
相关产品推荐

