You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cal.com Vanilla JavaScript嵌入SvelteKit失败,报错Cal未找到及500错误

Fixing Cal.com Embedding in SvelteKit (Cannot find 'Cal' & 500 Server Error)

I've run into this exact issue when embedding Cal.com in SvelteKit, and the problem boils down to two key factors: server-side rendering (SSR) limitations and missing type declarations for the global Cal variable. Here's how to fix it step by step:

1. Why You're Seeing These Errors

  • 500 Internal Error: SvelteKit runs your code on the server first, where the window object doesn't exist. The vanilla Cal.com init code tries to access window directly, which crashes during SSR.
  • "Cannot find name 'Cal'": Svelte's (or TypeScript's) type checker doesn't recognize the global Cal function injected by the Cal.com embed script.

2. Working Solution for SvelteKit

Option 1: Client-Side Only Initialization with onMount

Wrap the Cal.com init code in Svelte's onMount hook, which only runs in the browser (not on the server). This fixes the SSR issue, and we'll explicitly reference window.Cal to avoid type errors:

<script>
  import { onMount } from 'svelte';

  onMount(() => {
    // Inject the Cal.com embed script and initialize
    (function (C, A, L) {
      let p = function (a, ar) {
        a.q.push(ar);
      };
      let d = C.document;
      C.Cal =
        C.Cal ||
        function () {
          let cal = C.Cal;
          let ar = arguments;
          if (!cal.loaded) {
            cal.ns = {};
            cal.q = cal.q || [];
            d.head.appendChild(d.createElement("script")).src = A;
            cal.loaded = true;
          }
          if (ar[0] === L) {
            const api = function () {
              p(api, arguments);
            };
            const namespace = ar[1];
            api.q = api.q || [];
            typeof namespace === "string" ? (cal.ns[namespace] = api) && p(api, ar) : p(cal, ar);
            return;
          }
          p(cal, ar);
        };
    })(window, "https://cal.com/embed.js", "init");

    // Initialize Cal.com using window.Cal to bypass type checks
    window.Cal("init");
  });
</script>

<!-- Add your Cal.com embed element here -->
<div data-cal-link="your-cal-username/your-event-slug"></div>

Option 2: Add Type Declarations (For TypeScript Users)

If you're using TypeScript, you can declare the global Cal variable to avoid the "Cannot find name" error without using window.Cal:

  1. Create or edit src/app.d.ts in your SvelteKit project:
declare global {
  interface Window {
    Cal: (...args: any[]) => void;
  }
}

export {};
  1. Now you can use Cal("init") directly inside the onMount hook, just like the vanilla docs:
<script>
  import { onMount } from 'svelte';

  onMount(() => {
    // [Cal.com init code here]
    Cal("init"); // No more type errors!
  });
</script>

3. Alternative: Load the Script in app.html

If you want the Cal.com script loaded site-wide, you can add it to the end of the <body> tag in src/app.html:

<!-- src/app.html -->
<body>
  %sveltekit.body%
  <script>
    (function (C, A, L) {
      // [Cal.com init code here]
    })(window, "https://cal.com/embed.js", "init");
    Cal("init");
  </script>
</body>

This ensures the script runs only in the browser, but it's less flexible if you only need Cal.com on specific pages.

Key Takeaways

  • Always wrap browser-specific code (like accessing window or third-party scripts) in onMount in SvelteKit to avoid SSR crashes.
  • For global variables from third-party scripts, either reference them via window or add type declarations to keep your code type-safe.

内容的提问来源于stack exchange,提问作者acerblaze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:10:51