-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
💡 RFC: Once component - to render content only once per request #958
Comments
Isn't this just what |
The use-case that we always use is: imagine that you had 50 components in a list. If there was a script tag in the template for every component, you would end up with 50 duplicate script tags on the page. @matthewp I like it! Two questions that pops up:
I couldn't help but think while reading this: "this feels a lot like |
Oh! So it's more like C++ "pragma once" in that it's signaling to the compiler that only one instance of this should exist in compiled out code |
@jasikpark Yep, this is exactly like pragma once! |
@FredKSchott These get rendered in the same place they are authored. I'd recommend a Portal RFC to move things around as a first step. But that seems like a non-trivial compiler change to me. The other primary use case is . You define your svg once and then have use statements whenever it is used elsewhere. |
Bouncing off @aFuzzyBear, I was wondering if additional special attributes could be registered to emulate this behavior? <script once:last src="ref" />
<script once:last src="ref" />
<script once:last src="ref" /> <svg once:first><symbol id="ref-1" /><symbol id="ref-2" /></svg>
<svg><use href="#ref-1"></svg>
<svg once:first><symbol id="ref-1" /><symbol id="ref-2" /></svg>
<svg><use href="#ref-2"></svg> |
I was wondering if this could be used as a client:only:once with the :once used as an adverb the |
@aFuzzyBear, forgive a potentially daft question, but are there |
RFC Call: Consensus reached that this is something that we'd like to see added. No decision made on syntax, to be decided in this thread or a later RFC call if needed. |
This seems like a way to control “setup“ for an Astro component ( I wonder if the “once” framing to be a bit too imperative? I.e. what if an Astro Component appears within I think as some have pointed out with portals, we may also want some hooks into where things render. In the case of All that saying, maybe the framing of “once” is too prescriptive and maybe there’s an alternate framing that solves the original usecase. Or we separate |
Here's how you might make svgs easier in your application with svg use. First define your SVG in an Astro component. Circle.astro ---
import { Once } from 'astro/components';
---
<Once>
<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
<circle id="myCircle" cx="5" cy="5" r="4" stroke="blue"/>
</svg>
</Once>
<use href="#myCircle" x="10" fill="blue"/> Then use this component as many times as you want. <Circle />
<Circle />
<Circle />
<Circle />
<Circle /> Will render to: <svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
<circle id="myCircle" cx="5" cy="5" r="4" stroke="blue"/>
</svg>
<use href="#myCircle" x="10" fill="blue"/>
<use href="#myCircle" x="10" fill="blue"/>
<use href="#myCircle" x="10" fill="blue"/>
<use href="#myCircle" x="10" fill="blue"/>
<use href="#myCircle" x="10" fill="blue"/> |
I'm dropping this RFC as I think a lower-level API is needed first. There's currently not a great way to even know, inside of a component, how many times its been rendered. Rather than a high-level attribute/component (which still might be a nice convenience), I'd rather first see a way to know some metadata bout rendering. Maybe something like: ---
const renders = Astro.metadata.renderCount;
---
{renders === 0 ? <div>I'm rendering...</div> : ''} But this would be a new RFC. Probably I'd want to see if there were similar low-level use-cases that could use this sort of functionality (or other kinds of metadata). |
Slightly cursed, but what if someone wrote an "SVG Renderer" where the actual svg source is the library, and each usage of the svg in code is translated to |
I think even a renderer would not be able to implement this behavior without some help from Astro. I like #706 as a lower-level solution to this problem. |
Background & Motivation
#370 goes over the desire to have scripts that only render once. This has come up quite a bit.
Another case is
<svg>
when paired with<use>
, you only want the svg to render the first time.Proposed Solution
Possible solutions
I'm proposing a low-level
<Once>
component that renders into children only once per request. This allows you to make any content render only once.Later we can add things like
<Script>
or<Link>
that are merely wrappers around this Once component.Usage:
Alternatives considered
<script>s
. There are cases where you want the script to render more than once, such as when it's placed next to content it needs to mess with (like embeds). We could have made this optional but it might be confusing.<Script>
but since this is needed for other types of content it makes sense to start with a Once.Risks, downsides, and/or tradeoffs
None
Open Questions
astro/components
? (I think the latter)Detailed Design
No response
Help make it happen!
The text was updated successfully, but these errors were encountered: