Skip to content

Svelte Example

Demo WebsiteGitHub Source Code

Overview

This example demonstrates how to integrate ApiSorcery with Svelte projects. Svelte is a radical new approach to building user interfaces with a compiler-based architecture, and with TypeScript support, it provides an excellent developer experience with reactive state management.

Features

  • Type safety: Full TypeScript support with generated interfaces and types
  • Reactive stores: Svelte's reactive store patterns for state management
  • Axios integration: Built-in support for Axios HTTP client with interceptors
  • IntelliSense support: Full IDE support with auto-completion and type checking
  • Tree shaking: Optimized bundle size with ES modules support

Quick Setup

1. Install ApiSorcery

bash
npm install -g autoapi

2. Initialize Configuration

bash
autoapi init -l ts

This creates a .autoapirc.json configuration file:

json
{
  "application": {
    "language": "ts",
    "outputDir": "./src/api/auto"
  },
  "services": [
    {
      "code": "demo",
      "token": "72735b33815c4e5c9c2a924a8f4907ef",
      "version": 3,
      "enabled": true,
      "source": "https://your-api.com/swagger.json"
    }
  ]
}

3. Install Dependencies

bash
npm install axios
npm install -D @types/node

4. Generate API Client

bash
autoapi generate

5. Use in Svelte

svelte
<script lang="ts">
  import { onMount } from 'svelte';
  import * as ApiUser from '$lib/api/auto/demo/ApiUser';
  import type { User } from '$lib/api/auto/demo/model';

  let users: User[] = [];
  let loading = false;

  async function fetchUsers() {
    loading = true;
    try {
      const res = await ApiUser.getUserPaged({
        pagination: {
          page: 1,
          limit: 10,
        },
      });
      users = res.results || [];
    } catch (error) {
      console.error('Failed to fetch users:', error);
    } finally {
      loading = false;
    }
  }

  onMount(() => {
    fetchUsers();
  });
</script>

<div>
  {#if loading}
    <p>Loading...</p>
  {:else}
    <ul>
      {#each users as user (user.id)}
        <li>{user.name}</li>
      {/each}
    </ul>
  {/if}
</div>

Svelte Integration Patterns

Using Svelte Stores

typescript
// stores/users.ts
import { writable, derived } from 'svelte/store';
import * as ApiMain from '$lib/api/auto/demo/ApiMain';
import type { User } from '$lib/api/auto/demo/model';

function createUserStore() {
  const { subscribe, set, update } = writable<{
    data: User[];
    loading: boolean;
    error: Error | null;
  }>({
    data: [],
    loading: false,
    error: null,
  });

  return {
    subscribe,
    fetch: async () => {
      update(state => ({ ...state, loading: true, error: null }));
      try {
        const response = await ApiMain.getUsers();
        set({ data: response.data || [], loading: false, error: null });
      } catch (error) {
        update(state => ({ 
          ...state, 
          loading: false, 
          error: error as Error 
        }));
      }
    },
    reset: () => set({ data: [], loading: false, error: null }),
  };
}

export const userStore = createUserStore();

Using in Component

svelte
<script lang="ts">
  import { onMount } from 'svelte';
  import { userStore } from '$lib/stores/users';

  onMount(() => {
    userStore.fetch();
  });

  $: ({ data: users, loading, error } = $userStore);
</script>

<div>
  {#if loading}
    <p>Loading...</p>
  {:else if error}
    <p>Error: {error.message}</p>
  {:else}
    <ul>
      {#each users as user (user.id)}
        <li>{user.name}</li>
      {/each}
    </ul>
  {/if}
  <button on:click={() => userStore.fetch()}>Refresh</button>
</div>

Using with SvelteKit Load Functions

typescript
// routes/users/+page.ts
import type { PageLoad } from './$types';
import * as ApiMain from '$lib/api/auto/demo/ApiMain';

export const load: PageLoad = async () => {
  try {
    const response = await ApiMain.getUsers();
    return {
      users: response.data || [],
    };
  } catch (error) {
    return {
      users: [],
      error: error instanceof Error ? error.message : 'Failed to load users',
    };
  }
};
svelte
<!-- routes/users/+page.svelte -->
<script lang="ts">
  import type { PageData } from './$types';
  
  export let data: PageData;
</script>

<div>
  {#if data.error}
    <p>Error: {data.error}</p>
  {:else}
    <ul>
      {#each data.users as user (user.id)}
        <li>{user.name}</li>
      {/each}
    </ul>
  {/if}
</div>

Best Practices

  1. Type Definitions: Leverage generated TypeScript interfaces for better type safety
  2. Reactive Stores: Use Svelte stores for shared state across components
  3. Error Handling: Implement proper error handling in stores and components
  4. Request Interceptors: Use Axios interceptors for authentication and request/response transformation
  5. Environment Configuration: Use different API endpoints for development, staging, and production
  6. Code Splitting: Implement lazy loading for routes and API modules to optimize bundle size
  7. SvelteKit Integration: Utilize SvelteKit's load functions for server-side data fetching