Content Modeling in Svelte
Learn how to handle different content type and nestable blocks, render rich text, and use story references to manage content globally.
Setup
Copy this reference space, providing the intended structure to follow this guide. Make sure to update the access token.
Alternatively, in your existing space, create a new content type block article
and an “Articles” folder with content. The article content type block should have the following fields:
title
: Textcontent
: Rich text
Learn more about fields in the concept.
Create an article-overview
story as a page type content.
Finally, create a featured-articles
nestable block with the following field:
articles
: References
Add a new featured-articles
block to the body
field of the home story and select some articles to be featured.
Fetch and list all articles
Create new +page.js
and +page.svelte
files at src/routes/article-overview
to get all stories from this new content type.
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {
const { storyblokAPI } = await parent();
const articles = await storyblokAPI.getAll('cdn/stories', {
version: 'draft',
starts_with: 'articles',
content_type: 'article',
});
return {
articles
};
}
<script>
export let data
</script>
<h1>Article Overview</h1>
<ul>
{#each data.articles as article}
<li>
<a href="{article.full_slug}">{ article.content.title }</a>
</li>
{/each}
</ul>
Using the starts_with
parameter, only stories from the “Articles” folder are fetched. Using the content_type
parameter, the results are restricted to stories of the content type article
.
Learn more about parameters and filter queries in the Content Delivery API documentation.
Now, the /article-overview
route shows a list of links for all articles.
Create the article block
Add a new Article.svelte
component to render the new article content type.
<script>
import { renderRichText } from '@storyblok/svelte';
const { blok } = $props()
let renderedRichText = $derived(renderRichText(blok.content));
</script>
<h1>{blok.title}</h1>
<div>{@html renderedRichText}</div>
To render rich text fields, use the renderRichText
helper provided by the @storyblok/svelte
module.
Learn more about handling rich text in Storyblok in the fields concept and the @storyblok/richtext
package reference.
Update the layout file to add the new content type.
import { apiPlugin, storyblokInit, useStoryblokApi } from '@storyblok/svelte';
import Teaser from '$lib/Teaser.svelte';
import Feature from '$lib/Feature.svelte';
import Grid from '$lib/Grid.svelte';
import Page from '$lib/Page.svelte';
import Article from '$lib/Article.svelte';
export async function load() {
storyblokInit({
accessToken: import.meta.env.VITE_STORYBLOK_DELIVERY_API_TOKEN,
apiOptions: {
region: 'eu', // Choose the correct region from your Space.
},
use: [apiPlugin],
components: {
teaser: Teaser,
feature: Feature,
grid: Grid,
page: Page,
article: Article,
},
});
const storyblokAPI = await useStoryblokApi();
return {
storyblokAPI,
};
}
When clicking on links present in the article overview page, an article page renders correctly.
Handle referenced stories
In the +page.js
file, set the resolve_relations
parameter to get the full object response of referenced stories.
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {
const { storyblokAPI } = await parent();
const response = await storyblokAPI.get(`cdn/stories/${params.slug || "home"}`, {
version: 'draft',
resolve_relations: "featured-articles.articles"
});
return {
story: response.data.story,
};
}
Learn more in the references concept documentation.
Next, create a new FeaturedArticles.svelte
component.
<script>
import { storyblokEditable } from '@storyblok/svelte'
export let blok;
</script>
<section {...storyblokEditable(blok)}>
<h2>Featured Articles</h2>
<ul>
{#each blok.articles as article}
<li>
<a href="{article.full_slug}">
{article.content.title}
</a>
</li>
{/each}
</ul>
</section>
import { apiPlugin, storyblokInit, useStoryblokApi } from '@storyblok/svelte';
import Teaser from '$lib/Teaser.svelte';
import Feature from '$lib/Feature.svelte';
import Grid from '$lib/Grid.svelte';
import Page from '$lib/Page.svelte';
import Article from '$lib/Article.svelte';
import FeaturedArticles from '$lib/FeaturedArticles.svelte';
export async function load() {
storyblokInit({
accessToken: import.meta.env.VITE_STORYBLOK_DELIVERY_API_TOKEN,
apiOptions: {
region: 'eu', // Choose the correct region from your Space.
},
use: [apiPlugin],
components: {
teaser: Teaser,
feature: Feature,
grid: Grid,
page: Page,
article: Article,
['featured-articles']: FeaturedArticles,
},
});
const storyblokAPI = await useStoryblokApi();
return {
storyblokAPI,
};
}
Now, this component will render links to the featured articles in the home page of your project.
Previous Part
Dynamic Routing in Svelte