---
title: "@xid-kit/svelte"
description: "클라이언트 및 SSR 인증을 위한 Svelte 5 반응형 store와 SvelteKit 서버 hook."
locale: "ko"
---

> Documentation Index
> Fetch the locale documentation index at: https://xid.dev/ko/llms.txt
> Use this file to discover all available pages before exploring further.

# @xid-kit/svelte

## 상태

패키지 상태: **현재 패키지**. Svelte 5 store, SvelteKit 서버 hook, 헬퍼 유틸리티가 구현되었습니다. 프로덕션 인프라에서의 실제 IdP 왕복 테스트는 아직 수동 검증 대기 중입니다.

## 클라이언트 설정

루트 레이아웃에서 `createXidStores`와 `setXidContext`를 사용하여 store를 생성하세요. store는 Svelte store 구독자 계약을 충족하는 `XidClient.subscribe`를 사용합니다.

```svelte
<!-- +layout.svelte -->
<script lang="ts">
  import { setContext, onMount } from 'svelte'
  import { XidClient, createXidStores, setXidContext } from '@xid-kit/svelte'

  const client = new XidClient({ apiUrl: 'https://acme.xid.dev' })
  const stores = createXidStores(client)
  setXidContext(setContext, stores)

  onMount(() => {
const ac = new AbortController()
void client.load({ signal: ac.signal })
return () => ac.abort()
  })
</script>
<slot />
```

## 인증 상태 읽기

```svelte
<!-- Any child component -->
<script lang="ts">
  import { getContext } from 'svelte'
  import { getXidContext } from '@xid-kit/svelte'

  const { auth, user } = getXidContext(getContext)
  // $auth: { isLoaded, isSignedIn, userId, sessionId, session }
  // $user: discriminated union on isLoaded / isSignedIn / user
</script>

{#if !$auth.isLoaded}
  <p>Loading...</p>
{:else if $auth.isSignedIn}
  <p>Hello, {$user.isSignedIn ? $user.user.fullName : ''}</p>
{:else}
  <p>Not signed in</p>
{/if}
```

## 로그인 및 로그아웃

```svelte
<script lang="ts">
  import { getContext } from 'svelte'
  import { getXidContext, buildSignInUrl, executeSignOut } from '@xid-kit/svelte'

  const { client } = getXidContext(getContext)

  function handleSignIn() {
window.location.assign(buildSignInUrl('/sign-in', window.location.href))
  }

  async function handleSignOut() {
await executeSignOut(client, { redirectUrl: '/' })
  }
</script>
```

## 역할 및 권한 가드

```svelte
<script lang="ts">
  import { getContext } from 'svelte'
  import { getXidContext, isAllowed } from '@xid-kit/svelte'

  const { state } = getXidContext(getContext)
</script>

{#if isAllowed($state, { role: 'org:admin' })}
  <AdminPanel />
{/if}

{#if isAllowed($state, { permission: 'org:member:write' })}
  <EditButton />
{/if}
```

## SvelteKit 서버 hook

```ts
// src/hooks.server.ts
import { handleXid } from '@xid-kit/svelte/server'

export const handle = handleXid({
  jwtKey: JSON.parse(process.env.XID_JWT_KEY!),
  issuer: 'https://xid.dev',
  protectedRoutes: ['/dashboard', '/account'],
  signInUrl: '/sign-in',
})
```

## 로드 함수에서 인증 읽기

```ts
// +page.server.ts
import { redirect } from '@sveltejs/kit'
import { getXidAuth } from '@xid-kit/svelte/server'
import type { PageServerLoad } from './$types'

export const load: PageServerLoad = async ({ locals }) => {
  const auth = getXidAuth(locals)
  if (!auth.userId) throw redirect(303, '/sign-in')
  return { userId: auth.userId, orgId: auth.orgId }
}
```

## App.Locals 타입 정의

```ts
// src/app.d.ts
import type { AuthResult } from '@xid-kit/svelte/server'

declare global {
  namespace App {
interface Locals {
  xidAuth: AuthResult
}
  }
}
export {}
```

## 내보내진 API

| 내보내기 | 종류 | 모듈 |
| --- | --- | --- |
| `XidClient, createXidStores, setXidContext, getXidContext` | 클라이언트 설정 | `@xid-kit/svelte` |
| `buildSignInUrl, executeSignOut, isAllowed` | 유틸리티 | `@xid-kit/svelte` |
| `handleXid, getXidAuth` | 서버 hook | `@xid-kit/svelte/server` |

Source: https://xid.dev/ko/sdks/svelte/index.mdx
