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

SvelteKit store服务端有值,浏览器端返回undefined

问题原因及解决方案

核心问题

SvelteKit中服务端与客户端的Store实例完全隔离:你在+page.server.ts里设置的userSession值只存在于当前服务端请求的上下文里,不会自动同步到客户端。服务端渲染组件时,用的是当前请求的服务端Store实例,所以能打印出值;但客户端页面激活(hydrate)后,用的是浏览器全新的Store实例,初始值就是undefined,自然读不到服务端设置的内容。

正确实现方式

要让客户端能拿到用户会话数据,需要把数据持久化或传递到客户端,这里推荐两种常用方案:

方案1:通过Cookie传递+客户端Store初始化

  1. 服务端登录时把用户信息存入Cookie(生产环境建议加密处理)
    修改login/+page.server.ts:
import type { Actions } from './$types';
import { redirect } from '@sveltejs/kit';
import type { User } from './types';

export const actions: Actions = {
  default: async ({ cookies }) => {
    const user: User = {"username": "test", "email": "email@test.com"};
    // 写入Cookie,允许客户端读取(httpOnly设为false)
    cookies.set('user-session', JSON.stringify(user), {
      path: '/',
      httpOnly: false,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'strict',
      maxAge: 60 * 60 * 24 * 7 // 有效期7天
    });
    throw redirect(303, '/');
  }
};
  1. 改造Store,客户端初始化时从Cookie读取数据
    修改lib/stores.ts:
import { writable } from 'svelte/store';
import type { User } from '../login/types';

function createUserSession() {
  let initialValue: User | undefined;
  // 仅在客户端环境读取Cookie
  if (typeof window !== 'undefined') {
    const cookie = document.cookie
      .split('; ')
      .find(row => row.startsWith('user-session='))
      ?.split('=')[1];
    if (cookie) {
      initialValue = JSON.parse(decodeURIComponent(cookie));
    }
  }
  const { subscribe, set, update } = writable(initialValue);
  return {
    subscribe,
    set,
    update,
    // 新增登出方法,清除Cookie和Store值
    logout: () => {
      set(undefined);
      if (typeof window !== 'undefined') {
        document.cookie = 'user-session=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT';
      }
    }
  };
}

export const userSession = createUserSession();

方案2:利用SvelteKit Locals+Page Data传递

  1. 配置hooks.server.ts,从Cookie读取用户信息存入Locals
import type { Handle } from '@sveltejs/kit';
import type { User } from './login/types';

export const handle: Handle = async ({ event, resolve }) => {
  const sessionCookie = event.cookies.get('user-session');
  event.locals.user = sessionCookie ? JSON.parse(sessionCookie) as User : undefined;
  const response = await resolve(event);
  return response;
};
  1. 在根布局的服务端Load函数中传递用户数据
    +layout.server.ts:
import type { LayoutServerLoad } from './$types';

export const load: LayoutServerLoad = async ({ locals }) => {
  return { user: locals.user };
};
  1. 在根布局组件中初始化Store
    +layout.svelte:
<script lang="ts">
  import { userSession } from '$lib/stores';
  export let data;

  // 把服务端传递的用户数据同步到客户端Store
  $userSession = data.user;
</script>

<slot />

验证

修改后,客户端组件中访问$userSession就能正常拿到用户数据,服务端和客户端控制台都会输出正确的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:35:06