Sveltkit: Fetching global data in Slices

I am using SvelteKit in conjunction with Prismic at the company where I work, with SvelteKit being the primary technology in our stack. As a junior developer, I'm aware that I have much to learn. Prismic integration for SvelteKit has been available for about three months, yet there are only two basic tutorial videos on YouTube. The documentation is decent, yet it sometimes lacks detailed explanations.

I'm currently facing a challenge: I'm trying to understand how to import information from a custom type into my slice. I have an 'articles' slice with its main data (slice), but I'm struggling to import linked articles into it. So far, I haven't found any examples demonstrating how to do this in the index.svelte file for the articles slice.

My question revolves around routing. I've used "src/routes/+layout.server.js" to call my custom types for the navigation and footer, integrating them into my main layout. However, I'm uncertain about how to fetch articles using const documents = await client.getAllByType('article') and link this to the "src/lib/slices/Articles/index.svelte" file.

As a beginner, I hope my query doesn't come across as too naive. Given that Prismic's integration with SvelteKit is relatively new, finding comprehensive documentation or examples, especially for SvelteKit, has been challenging.

Hi Janis,

That's a great question, and Svelte offers a straightforward way to handle it:

// src/lib/slices/Example/index.svelte

<script>
  import { page } from "$app/stores"

  export let slice
</script>

<pre>
  {JSON.stringify($page, null, 2)}
</pre>

$page will contain all of the data that you have fetched in your +page.server.js file and any +layout.server.js file.

Let me know if you still have any questions.

Sam

But I have an article custom-type related to my Articles slice. My Question is, how can I make my articles show up in my Article slice? I have been stuck on this question for too long, no documentation helps out.

------------------------src\lib\slices\Actualites\index.svelte---------------------------------

<script>
	import SectionTitle from '$lib/components/typo/SectionTitle.svelte';

	/** @type {import("@prismicio/client").Content.ActualitesSlice} */
	export let slice;

</script>

<section
	data-slice-type={slice.slice_type}
	data-slice-variation={slice.variation}
	id={slice.primary.section_id}
	class="bg-white md:px-8 lg:px-14 2xl:px-20"
>
	<div class="h-[100px] flex items-center justify-around">
		<SectionTitle>
			{slice.primary.title}
		</SectionTitle>
	</div>

</section>

----------------src\routes[[preview=preview]]+page.server.js------------------

import { asText } from '@prismicio/client';

import { createClient } from '$lib/prismicio';

// @ts-ignore
export async function load({ fetch, cookies }) {
	const client = createClient({ fetch, cookies });

	const page = await client.getByUID('page', 'home');
	const articles = await client.getAllByType('articles');

	return {
		articles,
		page,
		title: asText(page.data.title),
		meta_description: page.data.meta_description,
		meta_title: page.data.meta_title,
		meta_image: page.data.meta_image.url
	};
}

export function entries() {
	return [{}];
}

-----------------------src\routes[[preview=preview]]+page.server.js---------------------------

import { asText } from '@prismicio/client';

import { createClient } from '$lib/prismicio';

// @ts-ignore
export async function load({ fetch, cookies }) {
	const client = createClient({ fetch, cookies });

	const page = await client.getByUID('page', 'home');
	const articles = await client.getAllByType('articles');

	return {
		articles,
		page,
		title: asText(page.data.title),
		meta_description: page.data.meta_description,
		meta_title: page.data.meta_title,
		meta_image: page.data.meta_image.url
	};
}

export function entries() {
	return [{}];
}

-------------------------------Console.log on my slice --------------------------------------


HI Janis,

Thanks for your patience and your follow-up. If you want to programmatically display the most recently updated articles from your website, you can do something like this:


<script>
	import { page } from '$app/stores'
 
	import SectionTitle from '$lib/components/typo/SectionTitle.svelte';

	/** @type {import("@prismicio/client").Content.ActualitesSlice} */
	export let slice;

</script>

<section
	data-slice-type={slice.slice_type}
	data-slice-variation={slice.variation}
	id={slice.primary.section_id}
	class="bg-white md:px-8 lg:px-14 2xl:px-20"
>
	<div class="h-[100px] flex items-center justify-around">
		<SectionTitle>
			{slice.primary.title}
		</SectionTitle>
		{#each $page.data.articles as article}
			<article>
				{article.id} // Template your article here
			</article>
		{/each}
	</div>

</section>

This will use the data from your +page.server.js file, where you query:

const articles = await client.getAllByType('articles');

However, based on your model it looks like you want to manually choose articles for each Slice. If that's the case, then you're on the right track. You just need to add a fetchLinks property to your API configuration in prismicio.js to retrieve the article content. That might look like this:

export const createClient = ({ cookies, ...config } = {}) => {
	const client = prismic.createClient(repositoryName, {
		routes,
		defaultParams: {
			fetchLinks: ["article.title", "article.description"] // Select all the properties you want here
		},
		...config
	});

	enableAutoPreviews({ client, cookies });

	return client;
};

However, fetchLinks will only fetch the first block of a rich text field. If you need multiple blocks from a rich text field, you should look into the more powerful graphQuery option.

Then you could adjust your slice like this:


<script>
	import SectionTitle from '$lib/components/typo/SectionTitle.svelte';

	/** @type {import("@prismicio/client").Content.ActualitesSlice} */
	export let slice;

</script>

<section
	data-slice-type={slice.slice_type}
	data-slice-variation={slice.variation}
	id={slice.primary.section_id}
	class="bg-white md:px-8 lg:px-14 2xl:px-20"
>
	<div class="h-[100px] flex items-center justify-around">
		<SectionTitle>
			{slice.primary.title}
		</SectionTitle>
		{#each slice.items as article}
			<article>
				{article.article.title} // Template your article here
			</article>
		{/each}
	</div>

</section>

(I haven't tested the above code snippets, so there may be issues.)

I hope this helps!

Sam

Thank you! I got confused with another solution from a different post. The initial solution works! Thank you very much!

https://community.prismic.io/t/re-get-all-custom-types-object-from-content-relationship-inside-a-slice-sveltekit/15188/2

1 Like

Awesome! I'm happy it works :slight_smile:

Be sure to post a link to your project when it's finished! We'd love to see how it turns out.

1 Like

Will do, building my company's website! :slight_smile:

1 Like