#Render a astro content entry in svelte

3 messages · Page 1 of 1 (latest)

half zenith
#

Hello! I am building a site with a shop.
The shop has a content collection, containing products, with data properties containing the title, product id (to create a payment) and price.
The body of the collection entry is the description of the product, that will be displayed in a modal (svelte component) when clicking on the product card.

My current code:

  • Shop component (src/components/Shop.svelte):
<script lang="ts">
import type { CollectionEntry } from "astro:content";
import Modal from "./Modal.svelte";
import type { AstroComponentFactory } from "astro/dist/runtime/server";

export let products: CollectionEntry<"shop">[];

let shownModal: Promise<AstroComponentFactory> | undefined = undefined
</script> 

<ol>
  {#each products as product}
    <!-- svelte-ignore a11y-click-events-have-key-events -->
    <li on:click={() => {shownModal = (product.render().then(({ Content }) => Content))}}>
      <h2>{product.data.title}</h2>
      <h3 class="align-end">{product.data.price}</h3>
    </li>
  {/each}
</ol>

<Modal showModal={shownModal !== undefined}>
  {#if shownModal !== undefined}
    {#await (shownModal) then M}
      <M />
    {/await}
  {/if}
</Modal>
  • Shop page (src/pages/shop.astro):
---
import Shop from '@/components/Shop.svelte'
import { CollectionEntry, getCollection } from 'astro:content'

const products: CollectionEntry<"shop">[] = await getCollection('shop');
---
<Shop client:load {products} />
crimson basinBOT
#

Hi @half zenith. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Hello! Based on the information extracts provided, I can't find any specific details about using Svelte components with Astro in the way you described. However, I can help you with rendering content from a collection in Astro.

To render content from a collection in Astro, you can use the getCollection function. Here's an example from the Astro documentation (https://docs.astro.build/en/guides/content-collections#using-content-in-astro-templates):

---
import { getCollection } from 'astro:content';
const blogEntries = await getCollection('blog');
---
<ul>
  {blogEntries.map(blogPostEntry => (
    <li>
      <a href={`/my-blog-url/${blogPostEntry.slug}`}>{blogPostEntry.data.title}</a>
      <time datetime={blogPostEntry.data.publishedDate.toISOString()}>
        {blogPostEntry.data.publishedDate.toDateString()}
      </time>
    </li>
  ))}
</ul>

In your case, you can replace 'blog' with 'shop' to fetch the shop collection. However, since you're using Svelte components, you might need to adapt the code to work with your specific use case.

For more information on Astro and its features, you can refer to the Astro documentation (https://docs.astro.build).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

Astro Documentation

Content collections help organize your Markdown and type-check your frontmatter with schemas.