#Conditionally rendering in Astro component based on slot content
7 messages · Page 1 of 1 (latest)
Hi @woven turret. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Yes, it is possible to conditionally render elements in an Astro component based on the content passed into a <slot/>. You can use the Astro.slots.has() function to check if content for a specific slot exists. This can be useful when you want to wrap slot contents, but only want to render the wrapper elements when the slot is being used.
Here is an example from the Astro documentation (https://docs.astro.build/en/reference/api-reference#astroslots):
---
---
<slot />
{Astro.slots.has('more') && ( <aside> <h2>More</h2> <slot name="more" /> </aside>)}
In this example, the <aside> element will only be rendered if there is content for the 'more' slot.
However, it's important to note that there are some limitations to this approach. As mentioned in a Github issue (https://github.com/withastro/astro/issues/3884), whether a slot will be fulfilled is not known until it is rendered. The Astro.slots.has() API only says that there is a child that the compiler discovered that might render.
If you want to conditionally render a component based on whether it has any content, you might need to provide two usages of your component based on whether the content is truthy:
{slotContent ? (
<Component>
<Fragment>
<slot />
</Fragment>
</Component>
) : (
<Component />
)}
In this example, if slotContent is truthy, the component with the slot is rendered. If slotContent is falsy, the component without the slot is rendered.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@woven turret kapa.ai is still learning and improving, please let us know how it did by reacting below
@winter sphinx is it possible to detect if there is any content in the default slot?
Let me check the knowledge base for you. One moment! :books:
Yes, it is possible to detect if there is any content in the default slot using the Astro.slots.has() function. You can check if the default slot has content by passing the string 'default' as an argument to the function.
Here is an example:
---
const hasContent = Astro.slots.has("default");
---
<div class="card">
{hasContent && <div class="card-content"><slot/></div>}
</div>
In this example, the card-content div will only be rendered if there is content for the default slot.
However, it's important to note that there are some limitations to this approach. As mentioned in a Github issue (https://github.com/withastro/astro/issues/9654), Astro.slots.has("default") might still return true even when the default <slot> has no content in it. This is because Astro.slots.has relies on static analysis rather than runtime values. In this case, Astro knows that default could have a value, so it returns true for Astro.slots.has.