Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapping content entries from a collection to slots doesn't work #10147

Closed
1 task
Trombach opened this issue Feb 17, 2024 · 2 comments
Closed
1 task

Mapping content entries from a collection to slots doesn't work #10147

Trombach opened this issue Feb 17, 2024 · 2 comments
Labels
needs triage Issue needs to be triaged

Comments

@Trombach
Copy link

Trombach commented Feb 17, 2024

Astro Info

Astro                    v4.4.0
Node                     v21.6.0
System                   Linux (x64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             @astrojs/tailwind
                         @astrojs/svelte
                         @astrojs/mdx

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

When mapping over entries from a content collection and passing a frontmatter value (or any value from the entry) as slot names, i.e slot={entry.data.slot} or slot={entry.id} there is an error indicating that the entry is undefined. The error only shows up at build time, there are no warnings or error in my IDE. Assigning a slot name from a normal variable does not cause the same error. I've confirmed with console logs that the entries are not undefined and the typescript types don't indicate that an entry could possibly not be defined.

---
const slotName = "panel-1";
const collection = await getCollection("home");
---
// works ✔️
<Slots>
  <div slot={slotName}
</Slots>

// doesn't cause an error during build ✔️
<Slots>
  {collection.map((entry) => <div slot={slotName}>{entry.id}</div>)}
</Slots>

// error during build ❌
<Slots>
  {collection.map((entry) => <div slot={entry.data.slot}>{entry.id}</div>)}
</Slots>

The attached codesandbox link hopefully demonstrates the issue.
The error message is entry is not defined

and here is the stacktrace printed in the browser

ReferenceError: entry is not defined
    at /home/lukast/repos/homepage/astro-homepage/src/components/Hero/Hero.astro:1:1
    at async bufferHeadContent (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/runtime/server/render/astro/render.js:108:25)
    at async renderToAsyncIterable (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/runtime/server/render/astro/render.js:126:5)
    at async renderPage (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/runtime/server/render/page.js:31:24)
    at async renderPage (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/core/render/core.js:50:20)
    at async callMiddleware (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/core/middleware/callMiddleware.js:12:10)
    at async #tryRenderRoute (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/core/pipeline.js:73:18)
    at async DevPipeline.renderRoute (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/core/pipeline.js:45:12)
    at async handleRoute (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/vite-plugin-astro-server/route.js:251:18)
    at async run (file:///home/lukast/repos/homepage/astro-homepage/node_modules/astro/dist/vite-plugin-astro-server/request.js:50:14)

What's the expected result?

Astro should be able to prerender the elements containing slot names with data from the entry frontmatter and no error should occur.

If there is a legitimate reason why this pattern doesn't work with slot names, then the error message should be improved and, unless I have missed it, the docs should be updated that this pattern is not usable with slots.

Link to Minimal Reproducible Example

https://codesandbox.io/p/devbox/thirsty-elbakyan-958qzc

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label Feb 17, 2024
@daniel-moya
Copy link

daniel-moya commented Feb 18, 2024

@Trombach
I'm not sure if this is not allow for some reason or is justt a bug, but I just found it doesn't have to do anything with content entries.

I tried

<Slots>
  {['panel-1', 'panel-2'].map(panel => <div slot={panel} />)}
</Slots>

I'm still getting An error ocurred: panel not defined.

I also tried.

<Slots>
  <div class="container">
    {['panel-1'].map(panel => <div slot={panel}>Hello</div>)}
  </div>
</Slots>

It doesn't throw an error, but it doesn't display the slots. If put a fallback for the slots, those will still be created.

I don't see my self an use case where you would want to create multiple named slots, and assign them dinamically, maybe if you provide some more context of what you are trying to actually achived by doing this, someone could offer some way to do it.

As showed in the docs, slots allow for composable layouts, if you are looking to display collection entries, you could just pass to the component the data you need from each entry.

@MoustaphaDev
Copy link
Member

Hey, thanks for taking the time to create an issue!
As @daniel-moya mentioned, it's not related to content collection. Using variables created inside loops as the value of a slot prop isn't possible currently.
We're aware of that limitation and are tracking the issue in withastro/compiler#868

@MoustaphaDev MoustaphaDev closed this as not planned Won't fix, can't repro, duplicate, stale Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage Issue needs to be triaged
Projects
None yet
Development

No branches or pull requests

3 participants