---
title: Content Modeling in Svelte
description: Learn how to handle custom blocks, render rich text, and use story references to manage content across your Svelte project.
url: https://storyblok.com/docs/guides/svelte/content-modeling
---

# 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

In the existing space, create the following blocks:

-   An `article` content type block with the following fields:
    -   `title`: Text
    -   `content`: Rich text
-   An `article-overview` content type block with the following field:
    -   `title`: Text
-   A `featured-articles` nestable block with the following field:
    -   `articles`: References

  

> [!NOTE]
> Learn more about fields in the [concept](/docs/concepts/fields).

Next, create an `Articles` folder, open it, and create the following stories:

-   A few stories that use the `article` content type.
-   An article overview story with a `article-overview` content type. Select the option **Define as root for the folder**.

Finally, add the `featured-articles` block to the `body` field of the **Home** story, and select articles to feature.

## 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.

src/routes/article-overview/+page.js

```javascript
/** @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
  };
}
```

src/routes/article-overview/+page.svelte

```html
<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`.

> [!NOTE]
> Learn more about parameters and filter queries in the [Content Delivery API documentation](https://www.storyblok.com/docs/api/content-delivery/v2).

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.

src/lib/Article.svelte

```html
<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.

> [!NOTE]
> Learn more about handling rich text in Storyblok in the [fields concept](/docs/concepts/fields) and the `@storyblok/richtext` [package reference](https://www.storyblok.com/docs/libraries/js/richtext).

Update the layout file to add the new content type.

src/routes/+layout.js

```javascript
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.

src/routes/\[...slug\]/+page.js

```javascript
/** @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,
  };
}
```

> [!NOTE]
> Learn more in the [references concept](https://www.storyblok.com/docs/concepts/references) documentation.

Next, create a new `FeaturedArticles.svelte` component.

src/lib/FeaturedArticles.svelte

```html
<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>
```

src/routes/+layout.js

```javascript
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 homepage of your project.

## Related resources

[Concept: Fields](/docs/concepts/fields)

[Concept: References](/docs/concepts/references)

[@storyblok/richtext Package Reference](https://www.storyblok.com/docs/libraries/js/richtext)

  

## Pagination

-   [Previous: Dynamic Routing in Svelte](/docs/guides/svelte/dynamic-routing)
