πŸ”₯Framework Integration

Integrating MeshBase with Svelte

Build blazing-fast Svelte applications powered by MeshBase. Reactive stores, SvelteKit, and Svelte's unique reactivityβ€”all covered.

Why MeshBase + Svelte?

⚑Truly Reactive

Svelte's compiler-based reactivity works perfectly with MeshBase. No virtual DOM, just fast updates.

🎯Minimal Boilerplate

Svelte + MeshBase = incredibly clean code. Less ceremony, more productivity.

πŸš€SvelteKit Ready

Server-side rendering, static generation, and load functions work seamlessly with MeshBase.

πŸ“¦Tiny Bundle Size

Svelte compiles away. MeshBase API calls add zero framework overhead to your bundle.

What You'll Need

  • βœ“Svelte 3+ or SvelteKit project
  • βœ“A MeshBase account with content types defined
  • βœ“Your MeshBase public API key

Quick Start: Basic Svelte

The simplest way to fetch MeshBase content in Svelte.

1. Add your API key

Create .env:

VITE_MESHBASE_API_URL=https://api.meshbase.io/v1
VITE_MESHBASE_API_KEY=your-api-key-here

2. Fetch in a component

Create BlogList.svelte:

<script>
  import { onMount } from 'svelte';
  
  const API_URL = import.meta.env.VITE_MESHBASE_API_URL;
  const API_KEY = import.meta.env.VITE_MESHBASE_API_KEY;
  
  let posts = [];
  let loading = true;
  let error = null;

  onMount(async () => {
    try {
      const response = await fetch(`${API_URL}/blog-posts`, {
        headers: {
          'Authorization': `Bearer ${API_KEY}`,
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) throw new Error('Failed to fetch');
      
      const json = await response.json();
      posts = json.data;
    } catch (err) {
      error = err.message;
    } finally {
      loading = false;
    }
  });
</script>

{#if loading}
  <div>Loading...</div>
{:else if error}
  <div>Error: {error}</div>
{:else}
  <div class="blog-list">
    {#each posts as post (post.id)}
      <article>
        <h2>{post.title}</h2>
        <p>{post.excerpt}</p>
        <a href="/blog/{post.id}">Read more</a>
      </article>
    {/each}
  </div>
{/if}
✨

That's It!

Your Svelte app now fetches content from MeshBase. Svelte's reactivity handles the restβ€”no additional state management needed!

Svelte Stores (Recommended)

For shared state across components, use Svelte stores.

Create a content store

Create stores/content.js:

import { writable } from 'svelte/store';

const API_URL = import.meta.env.VITE_MESHBASE_API_URL;
const API_KEY = import.meta.env.VITE_MESHBASE_API_KEY;

function createContentStore() {
  const { subscribe, set, update } = writable({
    posts: [],
    loading: false,
    error: null,
  });

  return {
    subscribe,
    
    async fetchPosts() {
      update(state => ({ ...state, loading: true, error: null }));

      try {
        const response = await fetch(`${API_URL}/blog-posts`, {
          headers: {
            'Authorization': `Bearer ${API_KEY}`,
            'Content-Type': 'application/json',
          },
        });

        if (!response.ok) throw new Error('Failed to fetch');
        
        const json = await response.json();
        update(state => ({ ...state, posts: json.data, loading: false }));
      } catch (err) {
        update(state => ({ ...state, error: err.message, loading: false }));
      }
    },

    reset() {
      set({ posts: [], loading: false, error: null });
    },
  };
}

export const contentStore = createContentStore();

Use in components

<script>
  import { onMount } from 'svelte';
  import { contentStore } from './stores/content';

  onMount(() => {
    contentStore.fetchPosts();
  });
</script>

{#if $contentStore.loading}
  <div>Loading...</div>
{:else if $contentStore.error}
  <div>Error: {$contentStore.error}</div>
{:else}
  <div class="blog-list">
    {#each $contentStore.posts as post (post.id)}
      <article>
        <h2>{post.title}</h2>
        <p>{post.excerpt}</p>
      </article>
    {/each}
  </div>
{/if}
🎯

$ Syntax

The $ prefix auto-subscribes to stores. Svelte automatically unsubscribes when the component is destroyed. Clean and simple!

SvelteKit Integration

Using SvelteKit? Server-side rendering and static generation work seamlessly.

Server load function

Create routes/blog/+page.server.js:

import { env } from '$env/dynamic/private';

export async function load() {
  const response = await fetch(`${env.MESHBASE_API_URL}/blog-posts`, {
    headers: {
      'Authorization': `Bearer ${env.MESHBASE_API_KEY}`,
      'Content-Type': 'application/json',
    },
  });

  if (!response.ok) {
    throw error(response.status, 'Failed to fetch posts');
  }

  const json = await response.json();

  return {
    posts: json.data
  };
}

Use loaded data

Create routes/blog/+page.svelte:

<script>
  export let data;
</script>

<div class="blog-list">
  {#each data.posts as post (post.id)}
    <article>
      <h2>{post.title}</h2>
      <p>{post.excerpt}</p>
      <a href="/blog/{post.id}">Read more</a>
    </article>
  {/each}
</div>

Dynamic routes

Create routes/blog/[id]/+page.server.js:

import { env } from '$env/dynamic/private';
import { error } from '@sveltejs/kit';

export async function load({ params }) {
  const response = await fetch(
    `${env.MESHBASE_API_URL}/blog-posts/${params.id}`,
    {
      headers: {
        'Authorization': `Bearer ${env.MESHBASE_API_KEY}`,
        'Content-Type': 'application/json',
      },
    }
  );

  if (!response.ok) {
    throw error(404, 'Post not found');
  }

  const post = await response.json();

  return { post };
}

And routes/blog/[id]/+page.svelte:

<script>
  export let data;
</script>

<article>
  <h1>{data.post.title}</h1>
  {#if data.post.coverImage}
    <img src={data.post.coverImage} alt={data.post.title} />
  {/if}
  {@html data.post.content}
</article>

Static Site Generation (Adapter Static)

Pre-render all pages at build time for maximum performance.

Install adapter-static

npm install -D @sveltejs/adapter-static

Configure svelte.config.js

import adapter from '@sveltejs/adapter-static';

export default {
  kit: {
    adapter: adapter({
      pages: 'build',
      assets: 'build',
      fallback: null
    })
  }
};

Prerender pages

Add to your page files:

// routes/blog/+page.js
export const prerender = true;
πŸš€

Blazing Fast!

Static generation + Svelte's tiny runtime + MeshBase content = one of the fastest possible web architectures. Perfect for blogs, docs, and marketing sites.

TypeScript Support

Add type safety to your MeshBase integration.

Define your types

Create lib/types.ts:

export interface BlogPost {
  id: string;
  title: string;
  excerpt: string;
  content: string;
  coverImage?: string;
  publishedAt: string;
}

export interface MeshBaseResponse<T> {
  data: T[];
  meta?: {
    total: number;
    page: number;
  };
}

Typed load function

// routes/blog/+page.server.ts
import { env } from '$env/dynamic/private';
import type { BlogPost, MeshBaseResponse } from '$lib/types';

export async function load() {
  const response = await fetch(`${env.MESHBASE_API_URL}/blog-posts`, {
    headers: {
      'Authorization': `Bearer ${env.MESHBASE_API_KEY}`,
      'Content-Type': 'application/json',
    },
  });

  const json: MeshBaseResponse<BlogPost> = await response.json();

  return {
    posts: json.data
  };
}

Next Steps