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

服务端加载HTML内容时的Hydration异常问题

解决Svelte中@html渲染Supabase HTML内容的 hydration 问题

问题症状

从Supabase加载的HTML内容,直接输出时显示为纯文本;用{@html}包裹后内容不显示,同时控制台出现hydration_html_changed警告。热重载(重新保存文件)后内容正常,但整页刷新时问题复现。

问题原因

Svelte的服务端渲染(SSR)与客户端hydration过程中内容不匹配:

  • 服务端渲染时,page.data.personalMessage可能尚未从Supabase获取到数据,服务端生成的DOM是空值或占位内容;
  • 客户端hydrate时,数据才加载完成,实际DOM内容与服务端渲染的初始DOM不一致,触发 hydration 警告,Svelte会放弃更新该节点,导致内容不显示;
  • 热重载时跳过了SSR的 hydration 流程,直接在客户端渲染最新数据,所以正常显示。

解决方案

1. 用await块等待数据就绪

通过{#await}确保数据加载完成后再渲染{@html},避免服务端与客户端的内容差异:

<!-- +page.svelte -->
<script>
    import { page } from '$app/state';
</script>

<h2>Hey !</h2>
<div>
    {#await page.data.personalMessage}
        <p>加载中...</p>
    {:then htmlContent}
        {@html htmlContent}
    {/await}
</div>

2. 禁用该节点的hydration

如果服务端无法提前获取到HTML内容,直接给包裹节点添加hydrate={false}属性,让客户端完全接管该节点的渲染,跳过 hydration 校验:

<!-- +page.svelte -->
<script>
    import { page } from '$app/state';
</script>

<h2>Hey !</h2>
<div>
    {page.data.personalMessage}
    <div hydrate={false}>
        {@html page.data.personalMessage}
    </div>
</div>

3. 确保服务端预取数据

在+page.server.js或+page.js中提前从Supabase获取数据,保证服务端渲染时已有完整的HTML内容,让服务端与客户端的DOM完全匹配:

// +page.server.js
import { supabase } from '$lib/supabase';

export async function load() {
    // 从Supabase获取HTML内容
    const { data, error } = await supabase
        .from('your_table_name')
        .select('personalMessage')
        .single();

    if (error) {
        console.error(error);
        return { personalMessage: '' };
    }

    return {
        personalMessage: data.personalMessage
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 13:32:19