Sveltkit slice variation bug

Hi, I've been attempting to add a variation of a contact form. The first variation is for contacting the company to inquire about a service or ask questions related to the company. The second variation is the support form, intended for when a client or user requires assistance with an issue. However, it appears that whenever I use my support slice, a bug occurs, resulting in the duplication of this slice on the page. I've tried removing and re-adding it, as well as unpublishing and republishing, and explored various options, but I continue to encounter the issue of double slices.

	import { enhance } from '$app/forms';
	import ParralaxFx from '$lib/components/layout/ParralaxFx.svelte';
	import RegularText from '$lib/components/typo/RegularText.svelte';
	import SectionTitle from '$lib/components/typo/SectionTitle.svelte';
	import { PrismicRichText } from '@prismicio/svelte';

	/** @type {import("@prismicio/client").Content.ContactSlice} */
	export let slice;
	
</script>

<section
	data-slice-variation={slice.variation}
	id="contact"
    class="grid grid-rows-3 md:grid-rows-none h-[650px] md:grid-cols-2 md:h-[450px] xl:h-[500px] text-center md:text-left"
>
	<div
		class="w-full overflow-hidden row-span-1 md:row-span-1 bg-brand-third order-last md:order-first shadow-inner"
	>
		{#if slice.primary?.image?.url}
			<ParralaxFx imageUrl={slice.primary.image.url} className="h-[650px]" />
		{/if}
	</div>

	<div
		class="bg-white row-span-2 md:row-span-1 order-first md:order-last w-full px-4 flex justify-around items-center"
	>
		<div class="flex flex-col gap-4 w-full px-4 md:px-0 md:w-[425px]">
			{#if slice.primary?.title}
				<SectionTitle>
					{slice.primary.title}
				</SectionTitle>
			{/if}

			{#if slice.primary?.description}
				<RegularText>
					<PrismicRichText field={slice.primary.description} />
				</RegularText>
			{/if}

			<form method="post" action="#contact" use:enhance class="flex flex-col gap-2">
				{#if slice.variation === 'supportForm' && slice.primary}
					<select>
						<option value="support">Support</option>
						<option value="sales">Sales</option>
						<option value="other">Other</option>
					</select>
				{/if}
				<input
					type="text"
					placeholder={slice.primary?.name_input_label}
					class="w-full h-[40px] p-2 border border-gray-300 rounded-md focus:outline-2 focus:outline-brand-fourth"
				/>
				<input
					type="email"
					placeholder={slice.primary?.mail_input_label}
					class="w-full h-[40px] p-2 border border-gray-300 rounded-md focus:outline-2 focus:outline-brand-fourth"
				/>
				<textarea
					placeholder={slice.primary?.message_input_label}
					class="w-full h-[110px] p-2 border border-gray-300 rounded-md resize-none focus:outline-3 focus:outline-brand-fourth"
				></textarea>
				<input
					type="submit"
					value={slice.primary?.submit_label}
					class="w-fit tracking-wider cursor-pointer bg-brand-fourth text-brand-first rounded-md hover:bg-brand-first hover:text-white transition-colors duration-500 px-4 py-3 shadow-md font-bold z-40 mx-auto md:mx-0"
				/>
			</form>
		</div>
	</div>
</section>


Hi @janisgaudreault.jg ,

Disclaimer: I'm a NextJS user considering exploring SvelteKit.

Now that I've said that, I wonder: Can you share a console.log of your slices object?

I'm actually spinning up my first sveltekit project now to see what I can figure out.

1 Like

When I console.log the slice, I get 2 different objects.

first:

{
    "variation": "default",
    "version": "initial",
    "items": [],
    "primary": {
        "title": "Support",
        "description": [
            {
                "type": "paragraph",
                "text": "Veuillez fournir les détails nécessaires pour que nous puissions vous aider le plus rapidement possible.",
                "spans": []
            }
        ],
        "image": {},
        "submit_label": "Envoyer",
        "name_input_label": "Votre nom",
        "mail_input_label": "Votre adresse e-mail",
        "message_input_label": "Votre message"
    },
    "id": "contact$baf2b3d9-6e02-4dbe-a90c-227a1891ce2d",
    "slice_type": "contact",
    "slice_label": null
}

second:

{"id": "contact$e66e2d9f-dbe2-4e07-bc7b-70f4cca7ba4f",
    "slice_type": "contact",
    "slice_label": null
}

The first slice is the default variation apparently. It looks as though the second object is missing quite a bit of data. Agreed?

Yes, but in the page where I use the default variation, everything seems fine. I do not get the duplication issue or missing data:

It's been my experience that slice variations are all handled within one index file. Are you sure that your variations are properly enclosed in conditionals? (please forgive my lack of svelte knowledge - I'm over here struggling just to get past the TypeScript issues on +page.server.ts) :man_facepalming:

The conditional seems to work because when I check if it is the support variation, it does display the topic selection fields, meanwhile, the default for the contact form does not.

By the way, Sveltkit is amazing, my favorite framework so far, the only issue is the documentation, it lacks sometimes with prismic since it is relatively new. TypeScript is good for making javascript more robust, but can get to be a headache sometimes. :rofl:

1 Like

So when I create a slice (default and variation) I get one file as expected. I'd think then there's a svelty way to conditionally render based on variation. Here's my best guess at this point:

	import type { Content } from '@prismicio/client';

	export let slice: Content.ContentSlice;
</script>
{#if slice.variation === 'code'}
<section data-slice-type={slice.slice_type} data-slice-variation={slice.variation}>
	Placeholder component for CODE VARIATION of the Content Slice
</section>
{/if}

{#if slice.variation === 'default'}
<section data-slice-type={slice.slice_type} data-slice-variation={slice.variation}>
	Placeholder component for DEFAULT Content Slice
</section>
{/if}

Is that how you'd do it?
ah... I see now you have this:

{#if slice.variation === 'supportForm' && slice.primary}
					<select>
						<option value="support">Support</option>
						<option value="sales">Sales</option>
						<option value="other">Other</option>
					</select>
				{/if}

slice.primary is an object and will always return true (I think). Perhaps you need to check for a particular property of primary?

	import { enhance } from '$app/forms';
	import ParralaxFx from '$lib/components/layout/ParralaxFx.svelte';
	import RegularText from '$lib/components/typo/RegularText.svelte';
	import SectionTitle from '$lib/components/typo/SectionTitle.svelte';
	import { PrismicRichText } from '@prismicio/svelte';

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

	console.log(slice);
	
</script>

<section
	data-slice-variation={slice.variation}
	id="contact"
    class="grid grid-rows-3 md:grid-rows-none h-[650px] md:grid-cols-2 md:h-[450px] xl:h-[500px] text-center md:text-left"
>
	<div
		class="w-full overflow-hidden row-span-1 md:row-span-1 bg-brand-third order-last md:order-first shadow-inner"
	>
		{#if slice.primary?.image?.url}
			<ParralaxFx imageUrl={slice.primary.image.url} />
		{/if}
	</div>

	<div
		class="bg-white row-span-2 md:row-span-1 order-first md:order-last w-full px-4 flex justify-around items-center"
	>
		<div class="flex flex-col gap-4 w-full px-4 md:px-0 md:w-[425px]">
			{#if slice.primary?.title}
				<SectionTitle>
					{slice.primary.title}
				</SectionTitle>
			{/if}

			{#if slice.primary?.description}
				<RegularText>
					<PrismicRichText field={slice.primary.description} />
				</RegularText>
			{/if}

			<form method="post" action="#contact" use:enhance class="flex flex-col gap-2">
				{#if slice.variation === 'supportForm' && slice.primary}
					<select>
						<option value="support">Support</option>
						<option value="sales">Sales</option>
						<option value="other">Other</option>
					</select>
				{/if}
				<input
					type="text"
					placeholder={slice.primary?.name_input_label}
					class="w-full h-[40px] p-2 border border-gray-300 rounded-md focus:outline-2 focus:outline-brand-fourth"
				/>
				<input
					type="email"
					placeholder={slice.primary?.mail_input_label}
					class="w-full h-[40px] p-2 border border-gray-300 rounded-md focus:outline-2 focus:outline-brand-fourth"
				/>
				<textarea
					placeholder={slice.primary?.message_input_label}
					class="w-full h-[110px] p-2 border border-gray-300 rounded-md resize-none focus:outline-3 focus:outline-brand-fourth"
				></textarea>
				<input
					type="submit"
					value={slice.primary?.submit_label}
					class="w-fit tracking-wider cursor-pointer bg-brand-fourth text-brand-first rounded-md hover:bg-brand-first hover:text-white transition-colors duration-500 px-4 py-3 shadow-md font-bold z-40 mx-auto md:mx-0"
				/>
			</form>
		</div>
	</div>
</section>

Technically, I just want to add a select input field for the user to pick a related topic to his question, so I simply added this in the slice, for now as I am building it up piece by piece`:

{#if slice.variation === 'supportForm' && slice.primary}
					<select>
						<option value="support">Support</option>
						<option value="sales">Sales</option>
						<option value="other">Other</option>
					</select>
				{/if}

As you can see, the condition is inside the form.

Perhaps check for a specific property in primary?

I'm guessing you have a repeatable zone for the select options?

I suppose then you'd be checking for slice.items.length > 0 not slice.primary

Or perhaps you have a boolean toggle for show select options.
If so, you'd probably check {#if slice.variation === 'supportForm' && slice.primary.showSelect}

I completely agree with you. The ID contact is not dynamic because I had a variable that I removed earlier to simplify the code, making it easier to debug step by step. I've now removed the ID, acknowledging your point that it isn't dynamic and we shouldn't have two different components with same IDs on a website. However, this change hasn't resolved the issue of the form appearing twice on my support page. I also removed the && slice.primary check since I do not need it for the moment as I am trying to debug the issue.

I really think it is a bug from prismic for some reason...

How does it look when you use slice simulator in slice machine?

I do not use the simulator in the slice machine because the margins where off and I wasn't able to see most of the component as I was coding it. So I build it and check on the local web page directly.

I totally understand that approach. Perhaps it might be worth it to try the simulator if only to inspect the slice object of the two variations and compare them?

I tried the SvelteKit minimal starter demo (YouTube video from Prismic). I created two variations of the RichText slice along with a conditional render. All appears to work as expected. I console.log the slices and get this:

    {
        "variation": "default",
        "version": "sktwi1xtmkfgx8626",
        "items": [
            {}
        ],
        "primary": {
            "content": [
                {
                    "type": "heading1",
                    "text": "Another Page",
                    "spans": []
                },
                {
                    "type": "paragraph",
                    "text": "Welcome to your other page.",
                    "spans": []
                },
                {
                    "type": "paragraph",
                    "text": "Go back to the homepage.",
                    "spans": [
                        {
                            "start": 0,
                            "end": 23,
                            "type": "hyperlink",
                            "data": {
                                "id": "ZBHc0BAAACoAz4-X",
                                "type": "page",
                                "tags": [],
                                "lang": "en-us",
                                "slug": "homepage",
                                "first_publication_date": null,
                                "last_publication_date": null,
                                "uid": "home",
                                "url": "/",
                                "link_type": "Document",
                                "isBroken": false
                            }
                        }
                    ]
                }
            ]
        },
        "id": "rich_text$c84cd334-7a7d-4915-b4ec-9af129daed3d",
        "slice_type": "rich_text",
        "slice_label": null
    },
    {
        "variation": "code",
        "version": "sktwi1xtmkfgx8626",
        "items": [],
        "primary": {
            "content": [
                {
                    "type": "preformatted",
                    "text": "Here's some code",
                    "spans": [],
                    "direction": "ltr"
                }
            ]
        },
        "id": "rich_text$6c5d06f8-bfac-4baa-8525-4d7ba4f5e980",
        "slice_type": "rich_text",
        "slice_label": null
    }
]

The RichText index.svelte

<section class="container">
	<PrismicRichText
		field={slice.primary.content}
		components={{
			label: Label
		}}
	/>
	{#if slice.variation === 'code'}
		<p>CODE</p>
	{/if}
</section>

Curious, eh?

Yes, very strange. Sorry for the late reply I was taking a break. My code is private because it is for my companies website. But if you happen to have questions about sveltkit or anything, it is our main stack. I am still a Junior but getting pretty good with that framework. :slight_smile:

1 Like

Hi @janisgaudreault.jg,

Thanks for flagging this! And thanks to @nf_mastroianni for all of the debugging.

After reading through your exchange, I'm suspecting that this might be a deeper bug — either in your data fetching or somewhere in Prismic. Janis, you shared the output from your console.log(). Where is that console.log() in your codebase? Is it in the slice component?

If you console.log() the data received in your load() function, do you have two contact slices? What about the data in your +page.server.js before you pass it to the <SliceZone /> component?

Also,

the only issue is the documentation, it lacks sometimes with prismic

I'd love to know about any issues you've struggled to find in the documentation. It's hard to know what we're missing, since we're so familiar with everything.

Sam