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

SvelteKit应用中Mailchimp数据获取后无法显示的问题排查

问题分析与解决方案

核心错误:Server Load函数返回格式不符合SvelteKit规范

你的+page.server.js中,load函数错误地将props嵌套在props字段中返回。SvelteKit服务器端的load函数不需要额外嵌套,直接返回包含属性的对象即可。当前返回结构导致页面组件无法正确接收campaigns数据。

修正+page.server.js的返回逻辑

将load函数中的返回语句从:

return {
  props: {
    campaigns: campaignData,
  },
};

改为:

return {
  campaigns: campaignData,
};

异常捕获部分同理,改为:

return {
  campaigns: [],
};

其他排查与优化点

  1. 确认路由访问路径
    文件位于Route>API目录下,对应访问路由应为/api(如http://localhost:5173/api)。若访问根路径/,不会触发该目录下的load函数。

  2. 响应式日志调试
    +page.svelte中的初始console.log(campaigns)仅在组件初始化时执行,此时服务器数据可能尚未返回。改为响应式日志,确保数据更新时能实时打印:

    <script>
        export let campaigns = [];
        $: console.log(campaigns); // 响应式监听数据变化
    </script>
    
  3. 检查Server端日志
    查看终端服务器日志:

    • 若未看到Campaigns Response或Formatted Campaign Data日志,说明load函数未被调用,需确认文件命名(必须为+page.server.js)和路由目录结构是否符合SvelteKit规则。
    • 若存在错误日志,根据提示排查API调用权限或参数问题。

修正后的完整代码示例

+page.server.js

import mailchimp from '@mailchimp/mailchimp_marketing';

const apiKey = import.meta.env.VITE_MAILCHIMP_API_KEY;

if (!apiKey) {
  throw new Error('API key is not defined. Please check your .env file.');
}

const serverPrefix = apiKey.split('-')[1];
mailchimp.setConfig({
  apiKey: apiKey,
  server: serverPrefix,
});

export async function load() {
  try {
    const campaignsResponse = await mailchimp.campaigns.list({ count: 10 });
    console.log('Campaigns Response:', campaignsResponse);

    const campaigns = campaignsResponse.campaigns || [];
    const campaignData = [];

    for (const campaign of campaigns) {
      const campaignReportResponse = await mailchimp.reports.get(campaign.id);
      const reports = campaignReportResponse;

      const reportData = {
        send_time: campaign.send_time,
        campaign_id: campaign.id,
        campaign_title: campaign.settings.title,
        subject_line: campaign.settings.subject_line,
        emails_sent: reports.emails_sent || 0,
        abuse_reports: reports.abuse_reports || 0,
        unsubscribed: reports.unsubscribed || 0,
        unsubscribe_rate: reports.emails_sent ? (reports.unsubscribed / reports.emails_sent) : 0,
        hard_bounces: reports.bounces?.hard_bounces || 0,
        soft_bounces: reports.bounces?.soft_bounces || 0,
        bounces: (reports.bounces?.hard_bounces || 0) + (reports.bounces?.soft_bounces || 0),
        syntax_errors: reports.bounces?.syntax_errors || 0,
        forwards_count: reports.forwards?.forwards_count || 0,
        forwards_opens: reports.forwards?.forwards_opens || 0,
        opens_total: reports.opens?.opens_total || 0,
        unique_opens: reports.opens?.unique_opens || 0,
        open_rate: reports.opens?.open_rate || 0,
        last_open: reports.opens?.last_open || null,
        clicks_total: reports.clicks?.clicks_total || 0,
        unique_clicks: reports.clicks?.unique_clicks || 0,
        unique_subscriber_clicks: reports.clicks?.unique_subscriber_clicks || 0,
        click_rate: reports.clicks?.click_rate || 0,
      };

      campaignData.push(reportData);
    }

    console.log('Formatted Campaign Data:', campaignData);

    // 直接返回props属性
    return {
      campaigns: campaignData,
    };
  } catch (error) {
    console.error('Error fetching Mailchimp data:', error.response ? error.response.body : error.message);
    
    return {
      campaigns: [],
    };
  }
}

+page.svelte

<script>
    export let campaigns = [];
    $: console.log(campaigns); // 响应式日志
</script>

{#if campaigns.length > 0}
    {#each campaigns as campaign}
        <div class="campaign">
            <h2>{campaign.campaign_title}</h2>
            <p><strong>主题:</strong> {campaign.subject_line}</p>
            <p><strong>发送时间:</strong> {new Date(campaign.send_time).toLocaleString()}</p>
            <p><strong>发送数量:</strong> {campaign.emails_sent}</p>
            <p><strong>投诉举报:</strong> {campaign.abuse_reports}</p>
            <p><strong>退订人数:</strong> {campaign.unsubscribed}</p>
            <p><strong>退订率:</strong> {(campaign.unsubscribe_rate * 100).toFixed(2)}%</p>
            <p><strong>硬退回:</strong> {campaign.hard_bounces}</p>
            <p><strong>软退回:</strong> {campaign.soft_bounces}</p>
            <p><strong>总退回:</strong> {campaign.bounces}</p>
            <p><strong>语法错误:</strong> {campaign.syntax_errors}</p>
            <p><strong>转发次数:</strong> {campaign.forwards_count}</p>
            <p><strong>转发打开次数:</strong> {campaign.forwards_opens}</p>
            <p><strong>总打开次数:</strong> {campaign.opens_total}</p>
            <p><strong>独立打开次数:</strong> {campaign.unique_opens}</p>
            <p><strong>打开率:</strong> {(campaign.open_rate * 100).toFixed(2)}%</p>
            <p><strong>最后打开时间:</strong> {campaign.last_open ? new Date(campaign.last_open).toLocaleString() : '无'}</p>
            <p><strong>总点击次数:</strong> {campaign.clicks_total}</p>
            <p><strong>独立点击次数:</strong> {campaign.unique_clicks}</p>
            <p><strong>独立订阅者点击次数:</strong> {campaign.unique_subscriber_clicks}</p>
            <p><strong>点击率:</strong> {(campaign.click_rate * 100).toFixed(2)}%</p>
            <p><strong>活动ID:</strong> {campaign.campaign_id}</p>
            <!-- 若需添加查看链接,请在+page.server.js的reportData中补充`archive_url: campaign.archive_url`字段 -->
        </div>
    {/each}
{:else}
    <p>暂无活动数据。</p>
{/if}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:59:53