These integration guides are not official documentation and the Strapi Support Team will not provide assistance with them.
Svelte is a modern JavaScript framework that compiles components into efficient JavaScript at build time, unlike React or Vue, which handle heavy lifting in the browser. It uses a reactive programming model where state changes directly update the DOM without the need for a virtual DOM. This results in smaller bundles and faster performance.
Svelte’s assignment-based reactivity updates the DOM automatically when variables change, using the $:
syntax. The framework also supports reactive statements, allowing developers to run code when dependencies change. With scoped styling and minimal code, Svelte enables fast, responsive user experiences.
Integrating Svelte with Strapi creates a powerful stack for modern web development, which combines a flexible back-end with a lightning-fast front-end. Strapi, a leading headless CMS, manages your content through a user-friendly admin interface that is ideal for non-technical users. It delivers content via REST and GraphQL APIs, providing flexibility for your Svelte app.
Svelte’s modular, maintainable components allow you to build reactive user interfaces, while Strapi handles content modeling. Customize your data structure in Strapi, then easily consume it in Svelte for versatile applications. You can start with REST APIs and switch to GraphQL as your app grows, all without altering your back-end setup.
You can use Strapi’s headless CMS to avoid the limitations of traditional CMS architectures and benefit from more control and scalability. Svelte’s efficiency, combined with Strapi’s flexibility, creates a stack that is both developer-friendly and user-oriented. The open-source nature of both tools provides transparency, community support, and extensive customization.
Deployment is straightforward with Strapi Cloud, or you can choose from various deployment options. Strapi’s v5 updates enhance performance and development tools, making it easier to integrate with Svelte.
Choosing to integrate Svelte with Strapi can help you create a clean separation of concerns—Strapi manages your content while Svelte delivers fast, reactive interfaces for a wide range of web applications.
Ready to build something amazing with Svelte and Strapi? Let's walk through how to integrate these powerful tools to create responsive, content-rich applications.
Before we start, make sure you have:
Visual Studio Code with the Svelte extension will make your coding experience much smoother.
Start by creating a fresh SvelteKit project. If you're evaluating different frameworks, this SvelteKit comparison provides insights into how SvelteKit stacks up against alternatives like Next.js.
1
npx sv create my-svelte-app
1
2
cd my-svelte-app
npm install
1
npm run dev
You're now running SvelteKit! The project structure includes src/routes/
for your pages and src/lib/
for your components and utilities.
Next, let's create your Strapi back-end:
1
npx create-strapi@latest my-strapi-api
When prompted with "Start with an example structure & data?", ensure you choose "yes".
http://localhost:1337/admin
. find
and findOne
for your Article collection type.This should enable your Article collection type to be publicly accessible using the API endpoint http://localhost:1337/api/articles
.
Let's integrate Svelte with Strapi's API:
./src/routes/articles/+page.js
file to get article data from Strapi before the route component renders. This is done by creating the load
function. Add the code below.1
2
3
4
5
6
7
8
// Path: ./src/routes/articles/+page.js
export const load = async ({ fetch }) => {
const res = await fetch('http://localhost:1337/api/articles');
const { data } = await res.json();
return { articles: data };
};
The return value is now available to the page via the articles
prop. Let's create the article page.
./src/routes/articles/+page.svelte
and add the code below:1
2
3
4
5
6
7
8
9
10
11
12
// Path: ./src/routes/articles/+page.svelte
<script>
let { data } = $props();
</script>
<h1>Svelte and Strapi Integration</h1><div>
{#each data.articles as article}
<h2>{article.title}</h2>
<p>{article.description}</p>
{/each}
</div>
This code fetches articles from Strapi and displays them in your Svelte app as shown below when you visit http://localhost:5173/articles
:
You can find the complete code for the project above here.
If you're unsure whether to use REST or GraphQL, consider reading about the REST vs GraphQL decision to make an informed choice that suits your project's needs.
For more complex data needs, GraphQL offers precise control:
1
npm install @urql/svelte
src/lib/graphql-client.js
:1
2
3
4
5
import { createClient } from '@urql/svelte';
export const client = createClient({
url: 'http://localhost:1337/graphql',
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script>
import { client } from '$lib/graphql-client';
import { gql } from '@urql/svelte';
import { onMount } from 'svelte';
let articles = [];
const ARTICLES_QUERY = gql`
query GetArticles {
articles {
data {
documentId
title
description
}
}
}
}
`;
onMount(async () => {
const response = await client.query(ARTICLES_QUERY).toPromise();
articles = response.data.articles.data;
});
</script>
<h1>Articles</h1>
{#each articles as article}
<h2>{article.title}</h2>
<p>{article.content}</p>
{/each}
This approach gives you precise control over what data you fetch.
config/middlewares.js
:1
2
3
4
5
6
7
8
module.exports = {
settings: {
cors: {
enabled: true,
origin: ['http://localhost:5173'], // Your SvelteKit dev server
},
},
};
/auth/local
endpoint to log in. .env
files:1
2
# In your SvelteKit project
VITE_STRAPI_URL=http://localhost:1337
import.meta.env.VITE_STRAPI_URL
.Reviewing Strapi Cron best practices can help ensure efficient and reliable background operations if your application requires scheduled tasks.
Follow these steps, and you will have a solid foundation for integrating Svelte with Strapi. As your app grows, remember to optimize queries, implement caching, and follow security best practices.
Let's dive into a real-world example—a blog platform built by integrating Svelte with Strapi. This project shows you practical implementation details and solutions to common challenges.
Our example is a modern blog that uses SvelteKit for the front-end and Strapi as the headless CMS. You can review the complete code on GitHub.
This blog platform features:
Here are some crucial aspects of how integrating Svelte with Strapi works:
load
function to grab blog posts:1
2
3
4
5
6
export const load = async ({ fetch }) => {
const res = await fetch('http://localhost:1337/api/articles');
const { data } = await res.json();
return { articles: data };
};
1
2
3
4
5
6
export async function load({ params, fetch }) {
const { slug } = params;
const res = await fetch(`http://localhost:1337/api/articles?filters[slug][$eq]=${slug}`);
const { data } = await res.json();
return { article: data[0] };
}
1
2
3
4
5
6
export const load = async ({ fetch }) => {
const res = await fetch('http://localhost:1337/api/articles');
const { data } = await res.json();
return { articles: data };
};
The project uses several techniques to maintain performance:
1
const formattedDate = $derived(new Date(article.publishedAt).toLocaleDateString());
1
const res = await fetch('http://localhost:1337/api/articles?populate=author');
1
2
export const csr = false;
export const prerender = true;
The project addresses several typical integration issues:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// config/middlewares.js
module.exports = [
'strapi::errors',
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'http:', 'https:'],
'img-src': ["'self'", 'data:', 'blob:', 'http:', 'https:'],
'media-src': ["'self'", 'data:', 'blob:', 'http:', 'https:'],
},
},
},
},
// ... other middlewares
];
1
2
3
4
5
6
7
8
9
10
11
12
13
async function login(email, password) {
const response = await fetch('http://localhost:1337/api/auth/local', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ identifier: email, password }),
});
const data = await response.json();
if (data.jwt) {
localStorage.setItem('token', data.jwt);
return true;
}
return false;
}
1
2
3
4
5
# .env
PUBLIC_STRAPI_URL=http://localhost:1337
# src/lib/api.js
const BASE_URL = import.meta.env.PUBLIC_STRAPI_URL;
If you have any questions about Strapi 5 or just would like to stop by and say hi, you can join us at Strapi's Discord Open Office Hours, Monday through Friday, from 12:30 pm to 1:30 pm CST: Strapi Discord Open Office Hours.
For more details, visit the Strapi documentation and the Svelte documentation.