Open trafnar opened 1 year ago
Thank you for the clean reproduction, it was really helpful!
I'll let one of the other maintainers confirm, but this seems to be an architectural limitation.
Due to Astro's streaming, we only wait until the page's frontmatter has run before generating the <head>
element. Frontmatter of a component (in your case, components/Post.astro
) cannot add scripts or stylesheets because by the time it's run, the <head>
is already sent to the browser so that it can start loading assets.
In case of SSG, it shouldn't matter, but the same architecture is used for both modes.
Just started exploring Astro yesterday and ran into this today. My component is a 1 off, so as a work around I set <style is:inline>
, but I can see how that's not useful in a loop.
If anyone finds this issue: I've worked around it by including the component in an Astro layout (.astro
) (wrapped in a hidden div), so the price we pay is duplicate HTML output (1x in the MDX, 1x in the layout), but assets (CSS & JS) are only added once.
I still think this is a kind of drastic limitation and should definitely be documented somewhere.
Duplicate issues
Closing those to keep the conversation going here.
Thanks for investigating @lilnasy! I'm not convinced this is an architectural limitation—it might just be a bug with how we crawl the module graph for styles.
There's currently some effort to improve that, but we had to move it behind an experimental flag for the time being. See some of the discussion in https://github.com/withastro/astro/issues/7857
Edit: unfortunately setting experimental: { optimizeHoistedScript: true }
doesn't fix this issue, but the issue is definitely related to that algorithm.
I tried using Imba code within Astro, using the Imba Vite plugin. I created an Imba component, wrapped it in an Astro component, then included that in an MDX file that was part of a content collection. This worked but the styles only appeared in development, not in production.
I think this is a similar issue, but its interesting that it works in development mode.
I have a reproduction of this which I was going to share on StackBlitz, but the Imba Vite plugin requires a newer version of Node than StackBlitz supports
@trafnar You can add codesandbox or a github repo in the reproduction.
@lilnasy good idea. I believe this issue is actually distinct so I've opened an issue with a reproducible example as a github repo #8436
@trafnar In development, styles are loaded using an import like so import "/src/imba-component.imba?imba&type=style&lang.css";
. It's because we're defaulting to emitCss = true
.
So it's working for both content collections and pages. (I think #8436 can be closed)
But in the build, styles are NOT included in content collection components. Stackblitz link to reproduce
whereas they are included in regular pages
So, from here it seems like Astro forgets to add the link tag in content collections 🤔
This might be the same cause as https://github.com/withastro/astro/issues/8399. I'm working on that one now.
@matthewp can't tell you how much I appreciate you working on this issue ❤️
Wrote up a proposal based on @matthewp
's idea: https://github.com/withastro/roadmap/discussions/707.
I have published an integration that fixes this issue. GitHub | NPM
I have tested it to be working against the original repro provided by trafnar (https://stackblitz.com/edit/github-u2yta7?file=src%2Fpages%2Findex.astro)
I think this is more of a limitation of how Content Collections works and probably not something that is fixable. However this feature might make this possible: https://caniuse.com/mdn-html_elements_link_blocking
Hi @lilnasy, I had been using your integration (not directly but I copied the code file, since svelte-check had an issue with the integration for some reason 🤔 ), thanks for that btw! I believe the workaround is not working anymore since the MDX 3.0 integration was released :(
I just came to say I'm using SSG and I do see this issue.
As a workaround, I include all the components available to .mdx pages in my layout, wrapped by a <template>
element. This has Astro include the styles in <head>
when building.
Edit: Unfortunately it's not a complete workaround. The component I'm using in turn uses an Icon
component from astro-icon
, and that one is broken (styles are OK but no icon showing).
I have found a workaround that works for me, but I know won't work for everyone.
In the file where you call entry.render()
to get the Content
component, pass in the components that are giving you trouble in to the components
prop on Content
. I'll use my blog's code for example:
---
import TroublesomeComponent from './components/TroublesomeComponent.astro'
// other stuff
const { Content: PostContent } = await entry.render()
---
<PostContent components={{ TroublesomeComponent }} />
This now makes TroublesomeComponent
globally available to any PostContent
I write, which then adds the script and styles to the <head>
.
Again, this might not be ideal, but I can live with this workaround and thought it might help others.
What version of
astro
are you using?2.9.1
Are you using an SSR adapter? If so, which one?
No
What package manager are you using?
npm
What operating system are you using?
Mac
What browser are you using?
Chrome
Describe the Bug
I'm looping through a content collection, using a component to render each content item. The content items themselves are defined in .mdx files, each with a component inside the mdx. That component does not get styling/scripts applied.
Reproducible example Stackblitz project
Basic Example of what's in the linked project
index.astro (some imports removed for brevity) ```astro --- const posts = (await getCollection("posts")); --- {posts.map((post) => )}
```
components/Post.astro
```astro
---
const { post } = Astro.props;
const { Content } = await post.render();
---
{post.data.title}
What's the expected result?
The
<Card />
component should have it's local styles applied.Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-u2yta7?file=src%2Fpages%2Findex.astro
Participation