Svelte Quick start guide

Estimated duration: 10 minutes

This guide shows you how to connect Prepr to a Svelte project to get data from Prepr CMS. You'll learn how to make a simple blog with Svelte and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.

Blog site end result

Info

Prerequisites

You need to have the following setup before you connect your Svelte project to Prepr.

Step 1: Create a new Svelte project

The instructions below will guide you on how to create an empty Svelte project for your blog app.

If you have an existing Svelte project, then you can skip this step.

  1. Execute the command below to create a new Svelte project called prepr-svelte. Choose a skeleton project and defaults for the remaining options.
npm create svelte@latest prepr-svelte
  1. When the project is successfully created, go to the prepr-svelte folder, the root directory of the project, and execute the commands below to start the project.
cd prepr-svelte
npm install
npm run dev
  1. You should now be able to view your app on your localhost, for example, http://localhost:5173/.

  2. Open your Svelte project with your preferred code editor.

  3. Go to the src/routes folder and update the +page.svelte file with the following code to display your blog:

<!-- ./src/routes/+page.svelte -->

<svelte:head>
    <title>My blog site</title>
</svelte:head>

<section>
    <h1>
        My blog site
    </h1>
</section>

You should now see something like the image below on your localhost.

view component

Step 2: Connect to Prepr

Set up a connection to Prepr to retrieve CMS data with GraphQL. The instructions below show you how to connect to Prepr directly from your project so that you can execute GraphQL queries to request data from the Prepr API.

  1. Create a folder called lib in the src folder. Then, create a file called prepr.js in this folder. Copy the following code to this file to set up the endpoint:
// ./src/lib/prepr.js 

import { PREPR_ENDPOINT } from '$env/static/private'

const prepr = async (query, variables) => {
    const response = await fetch(PREPR_ENDPOINT, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ query, variables }),
    })
    return response
}

export default prepr
  1. We recommend using environment variables to store sensitive information like access tokens. To add environment variables, create a .env file in the root directory of your project and add the API URL as follows:
# ./.env

PREPR_ENDPOINT=<YOUR-PREPR-API-URL>
  1. Replace the placeholder value <YOUR-PREPR-API-URL> with the API URL of an access token from Prepr. Get this URL by logging into your Prepr account:

    a. Go to Settings > Access tokens to view all the access tokens.

    b. Copy the API URL value from the GraphQL Production access token to only retrieve published content items.

access token list

Note

Use the GraphQL Production API URL to request published content items for your live app and use the GraphQL Preview value to make a preview of unpublished content items for your content editors.

If your app runs without errors, then the setup above was done correctly. The next step is to fetch content from Prepr using the endpoint that you set up.

Step 3: Fetch multiple articles

Now that your app is connected to Prepr, fetch the blog articles from Prepr.

Add a GraphQL query

  1. Create a queries directory in the lib folder that you just created and create a file named get-articles.js.

  2. Add the following query to this file to retrieve all articles:

// ./src/lib/queries/get-articles.js

const GetArticles = `
query {
    Articles {
        items {
            _id
            _slug
            title
        }
    }
}
`

export default GetArticles

Tip

If you’re using preloaded demo data in your Prepr CMS environment, as mentioned above in the Prerequisites section, you should have a few published articles as shown in the below image. The query will retrieve the ID, Slug, and Title of each article.

demo articles

In the next step, we'll fetch and process the query response.

Fetch data

Now that the query has been added, fetch the articles from Prepr and display them in the app.

  1. Go to the src/routes folder and create a file called +page.server.js to execute the query that you just created as follows:
// ./src/routes/+page.server.js

import prepr from '$lib/prepr'
import GetArticles from '$lib/queries/get-articles'

export async function load() {
    const response = await prepr(GetArticles)

    const { data } = await response.json()
    const { items } = data.Articles

    return {
        articles: items
    }
}
  1. Next, update the +page.svelte file to display the retrieved data by adding the following HTML:
<!-- ./src/routes/+page.svelte -->

<script>
    export let data;
</script>

<svelte:head>
    <title>My blog site</title>
</svelte:head>

<section>
    <h1>
        My blog site
    </h1>

<!-- list each retrieved article -->
    <ul>
        {#each data.articles as article}
            <li>
                {article.title}
            </li>
        {/each}
    </ul>
</section>

Now when you view the website on your localhost, you'll see something like the image below.

articles on site

Step 4: Fetch individual articles

Now that you have the list of articles, add links to them. When a visitor clicks on a link, your app should open a detailed article page automatically. The instructions below show you how to create a route from the main page to the detailed page and how to fetch the article details based on the slug of the article that was clicked.

First add links to the articles.

  1. Update the +page.svelte file to include a link on each article title as shown in the code below.
<!-- ./src/routes/+page.svelte -->

<script>
    export let data;
</script>

<svelte:head>
    <title>My blog site</title>
</svelte:head>

<section>
    <h1>
        My blog site
    </h1>

    <ul>
        {#each data.articles as article}
            <li>
      <!-- add link to reference an article slug -->
                <a href="{article._slug}">{article.title}</a>
            </li>
        {/each}
    </ul>
</section>

Now when you view the app, each article has its own link. When you click on the link, a new page opens with the slug in the URL, but a Page 404 error is displayed. Continue with the next step to fetch the article details and resolve this error.

Fetch article details

Add another query to fetch a specific article by its slug and make this page visible when clicking on an article.

  1. Create a file called get-article-by-slug.js in the queries folder and add the following query to this file to query a specific article by its slug:
// ./src/lib/queries/get-article-by-slug.js

const GetArticleBySlug = `
query ($slug: String) {
   Article (slug: $slug) {
     _id
     title
     content {
       __typename
       ... on Text {
         body
         text
       }
       ... on Assets {
         items {
           url
         }
       }
     }
   }
}`

export default GetArticleBySlug

Now that the query is added, fetch the individual article by its slug. Fetch the article title and the article content.

Note

  1. Go to src/routes/ and create a folder called [slug] and a new +page.server.js file with the following code to execute the query that you just created:
// ./src/routes/[slug]/+page.server.js

import prepr from '$lib/prepr'
import GetArticleBySlug from '$lib/queries/get-article-by-slug'

export async function load({ params }) {
    const response = await prepr(GetArticleBySlug, {slug: params.slug})

    const { data } = await response.json()

    return {
        article: data.Article
    }
}
  1. Create a new +page.svelte to display the article detail page as follows:
<script>
    export let data;
</script>

<svelte:head>
    <title>{data.article.title}</title>
</svelte:head>

<div>
    <h1>
        {data.article.title}
    </h1>

    {#each data.article.content as content}
        <div>
            {#if content.__typename === 'Assets'}
                <img src="{content.items[0].url}" width="300" height="250"/>
            {:else if content.__typename === 'Text'}
                {@html content.body}
            {/if}
        </div>
    {/each}
</div>

Now, when you view your site, you can click on an article which will direct you to that specific article like in the image below.

Article end result

All done

Congratulations! You have successfully connected a Svelte project to Prepr for a simple Blog app.

Next steps

To learn more on how to expand your project, check out the following resources: