> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Svelte 입문 — Inertia × Laravel에서 사용하는 기초 지식

> Laravel + Inertia.js에서 Svelte를 사용하는 입문 가이드. 컴파일러 기반 접근과 Svelte 5의 룬 구문부터, useForm · usePage 등의 Inertia Svelte 훅까지 실전적으로 설명합니다.

## Svelte란

[Svelte](https://svelte.jp/)는 JavaScript 프레임워크 중에서도 독자적인 위치를 차지하고 있습니다. React나 Vue가 **런타임 라이브러리**로 동작하는 것에 비해, Svelte는 **컴파일러**로 동작합니다. 빌드 시에 컴포넌트를 순수한 JavaScript로 변환하므로, 브라우저에 여분의 프레임워크 코드를 보낼 필요가 없습니다.

Svelte의 최대 특징은 **Virtual DOM을 사용하지 않는다**는 점입니다. 상태가 변화하면, Svelte가 컴파일 타임에 생성한 코드가 직접 DOM을 갱신합니다. 이로 인해 매우 경량이고 고속인 UI를 실현할 수 있습니다.

<Info>
  이 페이지에서 설명하는 것은 Svelte 5와 Inertia v3의 조합입니다. Laravel 13의 스타터 킷은 이 구성을 기본으로 사용합니다.
</Info>

### Svelte 5의 룬

Svelte 5(2024년 릴리스)에서는 \*\*룬(Runes)\*\*이라 불리는 새로운 리액티비티 시스템이 도입되었습니다. `$state` · `$derived` · `$effect` 등의 특별한 함수(룬)를 사용하여 리액티브한 상태를 선언합니다. Svelte 4 이전의 암묵적인 리액티비티와는 달리, 명시적이고 예측하기 쉬운 설계로 되어 있습니다.

```svelte theme={null}
<script lang="ts">
    let count = $state(0)

    function increment() {
        count++
    }
</script>

<button onclick={increment}>{count}</button>
```

<Tip>
  Laravel의 Svelte 스타터 킷은 Svelte 5 + TypeScript가 표준입니다. 본 페이지의 예시도 모두 TypeScript(`lang="ts"`)로 기술합니다.
</Tip>

***

## Laravel에서의 포지션

### 역사

Svelte와 Laravel의 관계는 Vue · React에 비해 매우 새로우며, **공식 스타터 킷**으로의 채용이 최초의 공식 지원입니다.

```mermaid theme={null}
timeline
    title Laravel과 Svelte의 여정
    2016 : Svelte 1 릴리스 (Rich Harris 작)
    2019 : Svelte 3 — 컴파일러 기반 설계로 쇄신
    2021 : Inertia.js — 커뮤니티에 의한 Svelte 어댑터 제공 개시
    2024 : Svelte 5 — 룬 구문 도입
    2026 : Laravel 13 — Svelte 스타터 킷 정식 추가 (Inertia v3 대응)
```

**2026년의 Laravel 13**에서 스타터 킷에 Svelte가 정식 추가된 것에 의해, Svelte는 Laravel 에코시스템에서의 공식 프론트엔드 선택지 중 하나가 되었습니다. Vue · React와 동렬로 취급되며, `laravel new`의 대화 프롬프트에서 선택할 수 있습니다.

Laravel 사용자에게는 아직 그다지 알려지지 않은 프레임워크이지만, **컴파일러에 의한 경량 번들**과 **심플한 구문**이 특징으로, Vue나 React에서 갈아타면 쓰는 양이 적은 것에 놀랄지도 모릅니다.

### 현재의 주류 스타일: Inertia × Svelte

현재 Laravel에서 Svelte 사용법의 중심은 **Inertia × Svelte**입니다. Inertia는 API를 설계하지 않고 Laravel의 컨트롤러에서 직접 Svelte 컴포넌트에 데이터를 전달할 수 있는 "모던 모놀리스" 아키텍처를 실현합니다.

```mermaid theme={null}
graph LR
    Browser["브라우저"]
    Inertia["Inertia.js<br>(어댑터 레이어)"]
    Laravel["Laravel<br>(컨트롤러)"]
    Svelte["Svelte<br>(페이지 컴포넌트)"]

    Browser <-->|XHR / 풀 페이지 로드| Inertia
    Inertia <-->|Inertia 응답| Laravel
    Inertia -->|props| Svelte
    Svelte -->|렌더링| Browser
```

***

## 셋업

### 스타터 킷 경유 (권장)

신규 프로젝트에서 시작하는 경우에는 스타터 킷을 사용하는 것이 가장 손쉽습니다.

```shell theme={null}
laravel new my-app
```

대화식 프롬프트에서 **Svelte**를 선택하면 이하가 모두 자동으로 셋업됩니다.

* `inertiajs/inertia-laravel` (서버사이드 어댑터)
* `@inertiajs/svelte` (클라이언트 어댑터)
* `svelte` + `@sveltejs/vite-plugin-svelte` (Svelte 5 본체와 Vite 플러그인)
* TypeScript + `svelte-check`
* Tailwind CSS + shadcn-svelte 컴포넌트 라이브러리
* `HandleInertiaRequests` 미들웨어
* 로그인 · 회원가입 등의 인증 화면 (Inertia + Svelte + TypeScript로 구현 완료)

### 수동 설치

기존 프로젝트에 추가하는 경우에는 서버사이드와 클라이언트사이드를 별도로 설치합니다.

```shell theme={null}
# 서버사이드 (PHP)
composer require inertiajs/inertia-laravel

# 클라이언트사이드 (JavaScript)
npm install @inertiajs/svelte @inertiajs/vite svelte
npm install --save-dev @sveltejs/vite-plugin-svelte svelte-check typescript
```

다음으로, `vite.config.ts`에 Svelte 플러그인과 Inertia Vite 플러그인을 추가합니다.

```ts theme={null}
import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import inertia from '@inertiajs/vite'

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.ts'],
            refresh: true,
        }),
        svelte(),
        inertia(),
    ],
})
```

`resources/js/app.ts`에서 Inertia 앱을 기동합니다. `@inertiajs/vite` 플러그인이 페이지의 자동 해결과 마운트를 수행하므로, 최소한의 엔트리 포인트만으로 충분합니다.

```ts theme={null}
import { createInertiaApp } from '@inertiajs/svelte'

createInertiaApp()
```

<Info>
  수동 설치의 세부 내용(루트 템플릿의 설정이나 미들웨어의 등록 등)은 [Inertia 공식 문서](https://inertiajs.com/installation)를 참고하세요.
</Info>

***

## 디렉터리 구조

스타터 킷에서는 Svelte의 페이지 컴포넌트를 `resources/js/pages/` 디렉터리에 배치합니다.

```
resources/js/
├── app.ts             # Inertia 앱의 기점
├── components/        # 재이용 가능한 UI 컴포넌트
│   └── ui/            # shadcn-svelte 컴포넌트
├── layouts/           # 레이아웃 컴포넌트
│   ├── AppLayout.svelte
│   └── AuthLayout.svelte
├── lib/               # 유틸리티 함수 · Svelte 룬 모듈
├── pages/             # Inertia 페이지 컴포넌트 (컨트롤러 이름에 대응)
│   ├── auth/
│   │   ├── Login.svelte
│   │   └── Register.svelte
│   ├── Dashboard.svelte
│   └── posts/
│       ├── Index.svelte
│       ├── Create.svelte
│       └── Show.svelte
└── types/             # TypeScript 타입 정의
```

`Inertia::render('posts/Index', [...])`이라고 쓰면 `resources/js/pages/posts/Index.svelte`가 대응하는 컴포넌트가 됩니다.

***

## Svelte 파일의 기본 구조

`.svelte` 파일은 \*\*`<script>` · 템플릿 · `<style>`\*\*의 3개 블록으로 구성됩니다.

```svelte theme={null}
<script lang="ts">
    // 로직 (TypeScript)
    let name = $state('Laravel')
</script>

<!-- 템플릿 (HTML 라이크한 표기법) -->
<h1>Hello, {name}!</h1>

<style>
    /* 스코프가 부여된 CSS (이 컴포넌트에만 적용) */
    h1 {
        color: #ff2d20;
    }
</style>
```

Vue의 Single File Component(SFC)와 비슷한 구조이지만, 템플릿과 스크립트의 기술량이 적은 것이 특징입니다. `<style>`은 기본으로 스코프가 한정되므로, 클래스 이름의 충돌을 걱정할 필요가 없습니다.

### 템플릿 구문

#### 변수 전개와 식

템플릿 내에서는 `{}`를 사용하여 JavaScript의 값이나 식을 삽입합니다.

```svelte theme={null}
<script lang="ts">
    let name = $state('세계')
    let count = $state(3)
</script>

<p>안녕하세요, {name}!</p>
<p>2배는 {count * 2}</p>
```

#### `{#if}` — 조건 분기

```svelte theme={null}
<script lang="ts">
    let isLoggedIn = $state(false)
    let role = $state('editor')
</script>

{#if isLoggedIn}
    <p>어서 오세요!</p>
{:else if role === 'admin'}
    <p>관리자로 로그인 중</p>
{:else}
    <a href="/login">로그인</a>
{/if}
```

Vue의 `v-if` / `v-else`, React의 삼항 연산자에 해당합니다.

#### `{#each}` — 리스트 렌더링

```svelte theme={null}
<script lang="ts">
    type Post = { id: number; title: string }
    let posts = $state<Post[]>([
        { id: 1, title: '첫 번째 게시물' },
        { id: 2, title: '두 번째 게시물' },
    ])
</script>

<ul>
    {#each posts as post (post.id)}
        <li>{post.title}</li>
    {/each}
</ul>
```

`(post.id)`는 키 지정이며, 효율적인 차분 갱신에 사용됩니다. Vue의 `v-for` / React의 `Array.map()`에 해당합니다.

#### `bind:` — 양방향 바인딩

`bind:value`를 사용하면, 폼 요소의 값과 리액티브 변수를 양방향으로 동기화할 수 있습니다.

```svelte theme={null}
<script lang="ts">
    let title = $state('')
    let agreed = $state(false)
    let role = $state('viewer')
</script>

<!-- 텍스트 입력 -->
<input bind:value={title} type="text" />
<p>입력 중: {title}</p>

<!-- 체크박스 -->
<input bind:checked={agreed} type="checkbox" />
<p>동의: {agreed}</p>

<!-- 셀렉트박스 -->
<select bind:value={role}>
    <option value="viewer">열람자</option>
    <option value="editor">편집자</option>
    <option value="admin">관리자</option>
</select>
```

Vue의 `v-model`에 해당합니다. React에서는 `onChange` 핸들러를 수기로 작성해야 했지만, Svelte에서는 `bind:`로 선언적으로 작성할 수 있습니다.

***

## 페이지 컴포넌트의 기본

Inertia의 페이지 컴포넌트는 일반적인 Svelte 컴포넌트입니다. Laravel의 컨트롤러에서 전달된 데이터를 props로 받을 수 있습니다.

### 컨트롤러

```php theme={null}
// app/Http/Controllers/PostController.php
use Inertia\Inertia;
use App\Models\Post;

class PostController extends Controller
{
    public function index()
    {
        return Inertia::render('posts/Index', [
            'posts' => Post::latest()->paginate(10),
        ]);
    }
}
```

### Svelte 페이지 컴포넌트

Svelte 5에서는 `$props()` 룬을 사용하여 props를 받습니다.

```svelte theme={null}
<!-- resources/js/pages/posts/Index.svelte -->
<script lang="ts">
    import { Link } from '@inertiajs/svelte'

    type Post = {
        id: number
        title: string
        created_at: string
    }

    type Props = {
        posts: {
            data: Post[]
        }
    }

    let { posts }: Props = $props()
</script>

<div>
    <h1>게시물 목록</h1>
    {#each posts.data as post (post.id)}
        <article>
            <h2>
                <Link href={`/posts/${post.id}`}>{post.title}</Link>
            </h2>
            <p>{post.created_at}</p>
        </article>
    {/each}
</div>
```

`$props()`로 props를 받는 것만으로, 컨트롤러에서 전달된 데이터를 템플릿에서 사용할 수 있습니다. REST API를 정의할 필요는 없습니다.

***

## `Link` 컴포넌트

`@inertiajs/svelte`가 제공하는 `<Link>` 컴포넌트를 사용하면, 페이지 전환이 XHR로 이루어져, 브라우저의 풀 리로드를 회피할 수 있습니다.

```svelte theme={null}
<script lang="ts">
    import { Link } from '@inertiajs/svelte'
</script>

<!-- 기본 링크 -->
<Link href="/posts">게시물 목록</Link>

<!-- POST 메서드로 링크 (삭제 등) -->
<Link href="/posts/1" method="delete" as="button">
    삭제
</Link>

<!-- 프리로드 (호버 시 사전 취득) -->
<Link href="/posts/1" preload>게시물 보기</Link>
```

일반적인 `<a>` 태그와 같은 방식으로 작성할 수 있지만, 뒤에서 Inertia가 페이지 컴포넌트만을 교체하므로 SPA 같은 조작감이 됩니다.

***

## `Form` 컴포넌트

`@inertiajs/svelte`가 제공하는 `<Form>` 컴포넌트는, 스타터 킷의 인증 화면에서 사용되고 있는 폼 송신의 권장 스타일입니다. `action`과 `method`를 props로 지정하고, 내부를 \*\*`{#snippet}`\*\*으로 기술합니다.

### 기본 사용법

```svelte theme={null}
<script lang="ts">
    import { Form } from '@inertiajs/svelte'
</script>

<Form action="/posts" method="post" class="flex flex-col gap-4">
    {#snippet children({ errors, processing })}
        <div>
            <label for="title">제목</label>
            <input id="title" name="title" type="text" required />
            {#if errors.title}
                <p class="error">{errors.title}</p>
            {/if}
        </div>

        <div>
            <label for="content">본문</label>
            <textarea id="content" name="content"></textarea>
            {#if errors.content}
                <p class="error">{errors.content}</p>
            {/if}
        </div>

        <button type="submit" disabled={processing}>
            {processing ? '전송 중...' : '게시하기'}
        </button>
    {/snippet}
</Form>
```

`{#snippet children({ errors, processing })}`는 Svelte의 스니펫 구문으로, 컴포넌트에 전달할 콘텐츠 블록입니다 (Vue의 슬롯이나 React의 render props에 해당). `errors`와 `processing`은 `Form` 컴포넌트가 자동으로 산출하여 전달해 줍니다. 폼 필드에는 `bind:value`가 아니라 HTML 네이티브의 `name` 속성을 사용하며, 브라우저의 표준 폼 데이터 수집이 기능합니다.

### 스타터 킷의 패턴

스타터 킷은 [Wayfinder](/ko/blog/wayfinder-introduction)를 사용하여 라우트를 오브젝트로 관리하고 있습니다. `store.form()`은 라우트 오브젝트의 `action`과 `method`를 포함하는 오브젝트를 반환하고, `<Form>`에 spread합니다.

```svelte theme={null}
<script lang="ts">
    import { Form } from '@inertiajs/svelte'
    import { store } from '@/routes/login'
</script>

<Form
    {...store.form()}
    resetOnSuccess={['password']}
    class="flex flex-col gap-6"
>
    {#snippet children({ errors, processing })}
        <!-- 폼 내용 -->
    {/snippet}
</Form>
```

`resetOnSuccess`에 지정한 필드는 송신 성공 시에 자동으로 리셋됩니다. 패스워드 필드 등 송신 후에 비우고 싶은 필드에 지정합니다.

<Info>
  Wayfinder를 사용하지 않는 경우는 `action="/login"`처럼 직접 URL을 전달하면 같은 방식으로 동작합니다.
</Info>

***

## `useForm` 훅

폼 처리에는 `@inertiajs/svelte`의 `useForm` 훅을 사용합니다. 폼의 상태 관리 · 송신 · 유효성 검증 오류 표시가 심플하게 구현됩니다.

### 컨트롤러 측

```php theme={null}
// app/Http/Controllers/PostController.php
class PostController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'title'   => ['required', 'string', 'max:255'],
            'content' => ['required', 'string'],
        ]);

        Post::create($validated + ['user_id' => auth()->id()]);

        return redirect()->route('posts.index')
            ->with('success', '게시물을 작성했습니다.');
    }
}
```

### Svelte 폼 컴포넌트

```svelte theme={null}
<!-- resources/js/pages/posts/Create.svelte -->
<script lang="ts">
    import { useForm } from '@inertiajs/svelte'

    const form = useForm({
        title: '',
        content: '',
    })

    function submit(e: SubmitEvent) {
        e.preventDefault()
        form.post('/posts')
    }
</script>

<form onsubmit={submit}>
    <div>
        <label>제목</label>
        <input type="text" bind:value={form.data.title} />
        {#if form.errors.title}
            <p class="error">{form.errors.title}</p>
        {/if}
    </div>

    <div>
        <label>본문</label>
        <textarea bind:value={form.data.content}></textarea>
        {#if form.errors.content}
            <p class="error">{form.errors.content}</p>
        {/if}
    </div>

    <button type="submit" disabled={form.processing}>
        {form.processing ? '전송 중...' : '게시하기'}
    </button>
</form>
```

`useForm`이 반환하는 오브젝트의 주요 프로퍼티를 정리합니다.

| 프로퍼티 / 메서드         | 설명                        |
| ------------------ | ------------------------- |
| `form.data`        | 폼의 데이터 오브젝트               |
| `form.errors`      | 유효성 검증 오류 (필드명으로 접근)      |
| `form.processing`  | 송신 중은 `true` (버튼 무효화에 사용) |
| `form.isDirty`     | 초기값에서 변경된 경우 `true`       |
| `form.post(url)`   | POST 요청으로 송신              |
| `form.put(url)`    | PUT 요청으로 송신 (갱신)          |
| `form.delete(url)` | DELETE 요청으로 송신            |
| `form.reset()`     | 폼을 초기값으로 리셋               |

유효성 검증 오류가 반환되었을 때, `useForm`은 입력 내용을 유지한 채 오류를 표시합니다. `bind:value`와의 조합으로 심리스한 폼 경험을 실현할 수 있습니다.

***

## 공유 데이터 (Shared Data)

모든 페이지에서 공통으로 필요한 데이터(로그인 중인 사용자 정보 · 플래시 메시지 등)는 `HandleInertiaRequests` 미들웨어의 `share()` 메서드로 정의합니다.

```php theme={null}
// app/Http/Middleware/HandleInertiaRequests.php
use Illuminate\Http\Request;
use Inertia\Middleware;

class HandleInertiaRequests extends Middleware
{
    public function share(Request $request): array
    {
        return array_merge(parent::share($request), [
            'auth' => [
                'user' => $request->user()
                    ? $request->user()->only('id', 'name', 'email')
                    : null,
            ],
            'flash' => [
                'success' => $request->session()->get('success'),
                'error'   => $request->session()->get('error'),
            ],
        ]);
    }
}
```

Svelte 컴포넌트에서 공유 데이터에 접근하려면 `usePage()`를 사용합니다.

```svelte theme={null}
<script lang="ts">
    import { usePage } from '@inertiajs/svelte'

    type SharedProps = {
        auth: {
            user: { id: number; name: string; email: string } | null
        }
        flash: {
            success: string | null
            error: string | null
        }
    }

    const page = usePage<SharedProps>()
</script>

<header>
    {#if page.props.auth.user}
        <span>{page.props.auth.user.name}</span>
    {:else}
        <span>게스트</span>
    {/if}
</header>

{#if page.props.flash.success}
    <div class="alert-success">{page.props.flash.success}</div>
{/if}
```

<Info>
  공유 데이터는 모든 요청에 포함되므로, 필요 최소한의 데이터로 좁힐 것을 권장합니다. `fn()`을 사용한 지연 평가로 하면, 실제로 접근되었을 때만 평가됩니다.
</Info>

***

## Svelte 5의 리액티비티 (룬)

Inertia × Svelte로 개발할 때 알아 두어야 할 Svelte 5의 룬 구문을 소개합니다.

### `$state` — 리액티브한 상태

```svelte theme={null}
<script lang="ts">
    let count = $state(0)
    let isOpen = $state(false)
    let items = $state<string[]>([])
</script>

<p>{count}</p>
<button onclick={() => count++}>+1</button>
<button onclick={() => isOpen = !isOpen}>토글</button>
```

`$state`로 선언한 변수는 자동으로 리액티브가 됩니다. 값이 바뀌면 DOM이 자동 갱신됩니다. Vue의 `ref`나 React의 `useState`에 해당하지만, `.value` 프로퍼티로의 접근이 불필요하며, 대입하는 것만으로 상태를 갱신할 수 있습니다.

### `$derived` — 파생된 값

```svelte theme={null}
<script lang="ts">
    let posts = $state<{ title: string; published: boolean }[]>([])

    // published가 true인 게시물만 추출
    let publishedPosts = $derived(posts.filter(post => post.published))

    // 여러 의존관계가 있는 경우
    let summary = $derived.by(() => {
        const total = posts.length
        const published = publishedPosts.length
        return `전 ${total}건 중 ${published}건 공개`
    })
</script>

<p>{summary}</p>
```

`$derived`는 의존하는 값이 바뀌면 자동으로 재계산됩니다. Vue의 `computed`나 React의 `useMemo`에 해당합니다.

### `$effect` — 부수 효과 처리

```svelte theme={null}
<script lang="ts">
    let query = $state('')

    // query가 바뀔 때마다 실행
    $effect(() => {
        console.log('검색 쿼리가 바뀌었습니다:', query)

        // 클린업 함수를 반환할 수 있음
        return () => {
            console.log('클린업')
        }
    })
</script>

<input bind:value={query} placeholder="검색..." />
```

`$effect`는 의존하는 `$state` 값이 변화할 때마다 실행됩니다. React의 `useEffect`에 해당하지만, 의존 배열을 명시할 필요가 없고, 사용한 `$state` 변수가 자동으로 추적됩니다.

***

## shadcn-svelte 컴포넌트

스타터 킷에는 [shadcn-svelte](https://www.shadcn-svelte.com/)가 편입되어 있습니다. shadcn-svelte는 React용 shadcn/ui와 같은 설계 사상을 가진 컴포넌트 라이브러리로, 코드를 프로젝트에 복사하여 자유롭게 커스터마이즈할 수 있습니다.

### 컴포넌트 추가

```shell theme={null}
npx shadcn-svelte@latest add button
npx shadcn-svelte@latest add input
npx shadcn-svelte@latest add card
```

명령을 실행하면 `resources/js/components/ui/`에 컴포넌트의 소스 코드가 배치됩니다.

### 사용법

```svelte theme={null}
<script lang="ts">
    import { Button } from '@/components/ui/button'
    import { Input } from '@/components/ui/input'
    import * as Card from '@/components/ui/card'
    import { useForm } from '@inertiajs/svelte'

    const form = useForm({ email: '', password: '' })

    function submit(e: SubmitEvent) {
        e.preventDefault()
        form.post('/login')
    }
</script>

<Card.Root class="w-96">
    <Card.Header>
        <Card.Title>로그인</Card.Title>
    </Card.Header>
    <Card.Content>
        <form onsubmit={submit} class="space-y-4">
            <Input
                type="email"
                bind:value={form.data.email}
                placeholder="메일 주소"
            />
            {#if form.errors.email}
                <p class="text-sm text-red-500">{form.errors.email}</p>
            {/if}

            <Input
                type="password"
                bind:value={form.data.password}
                placeholder="패스워드"
            />

            <Button type="submit" disabled={form.processing} class="w-full">
                {form.processing ? '로그인 중...' : '로그인'}
            </Button>
        </form>
    </Card.Content>
</Card.Root>
```

스타터 킷에는 Button · Input · Card · Dialog · Dropdown 등 자주 사용하는 컴포넌트가 미리 포함되어 있습니다. 추가하고 싶은 컴포넌트는 `npx shadcn-svelte@latest add` 명령으로 그때그때 추가할 수 있습니다.

***

## 정리

Svelte는 Laravel과의 조합에서, 특히 Inertia를 경유한 "모던 모놀리스" 구성에서 힘을 발휘합니다. 컴파일러 기반 설계에 의해 번들 크기가 작고, 룬 구문에 의해 리액티비티가 명시적이고 이해하기 쉬운 것이 특징입니다.

| 요소                  | 역할                            |
| ------------------- | ----------------------------- |
| Laravel 컨트롤러        | 라우팅 · 데이터 취득 · 유효성 검증         |
| `Inertia::render()` | 컨트롤러에서 Svelte 컴포넌트로 데이터 전달    |
| Svelte 페이지 컴포넌트     | `$props()`로 props를 받고 UI를 렌더링 |
| `useForm`           | 폼의 상태 관리 · 송신 · 오류 표시         |
| `Link` 컴포넌트         | 풀 리로드 없는 페이지 전환               |
| `usePage().props`   | 공유 데이터로의 접근                   |
| shadcn-svelte       | 표준 컴포넌트 라이브러리                 |

Inertia × Svelte를 사용하면, Laravel 백엔드의 심플함과 Svelte의 컴팩트한 기술 스타일을 조합한 개발 경험을 얻을 수 있습니다. 스타터 킷으로 프로젝트를 생성하면 인증 화면도 포함해서 바로 개발을 시작할 수 있습니다.

<Card title="Inertia.js 공식 문서" icon="book-open" href="https://inertiajs.com">
  Inertia v3의 전체 기능에 대해서는 공식 문서를 참고하세요.
</Card>


## Related topics

- [React 입문 — Inertia × Laravel에서 사용하는 기초 지식](/ko/blog/react-introduction.md)
- [Vue.js 입문 — Inertia × Laravel에서 사용하는 기초 지식](/ko/blog/vue-introduction.md)
- [Laravel을 시작하기 전에 필요한 지식](/ko/true-tutorial.md)
- [인증 입문](/ko/authentication.md)
- [프런트엔드](/ko/frontend.md)
