-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Supporting CSS-in-JS #4432
Comments
This looks great! Is one of the goals of this to get documentation into the docs site? |
Yup! After testing everything (including some more advanced cases) and fixing anything that's fixable by Astro, I believe we want to document what works, what doesn't work, and suggest alternatives. |
I feel like it should be possible to fix The As for @matthewp Would it be possible for Astro to allow hooking into the rendering pipeline? That might solve both of these issues. Footnotes
|
@mayank99 Since these are for React apps I think it makes the most sense that this is part of some API for the React renderer. That might also require core Astro changes, I'm not sure. There already is a hook into the rendering pipeline via the renderer API, so it might be possible to prototype this idea as a separate renderer before plugging it into the React render (although either approach is reasonable). You'd want it to work with streaming, it looks like styled-components has as solution for that: https://styled-components.com/docs/advanced#streaming-rendering |
This comment was marked as outdated.
This comment was marked as outdated.
Another lib worth trying is |
@nstepien I did look into astroturf but excluded it from the list because there is no vite/rollup plugin and the library does not look like it's maintained anymore. |
I've not tried it myself, but the docs do mention a rollup plugin: https://4catalyzer.github.io/astroturf/setup |
Also btw https://github.com/typestyle/typestyle worked fine when i tried it. |
@osdiab I've added an example for typestyle and updated the table. Thanks for the recommendation. |
@mayank99 if you have failing Stackblitz examples for the ones that are possibly bugs that would be helpful for debugging. |
@matthewp You should be able to open the examples repo in stackblitz. https://stackblitz.com/github/mayank99/astro-css-in-js-tests/tree/main/styled-components Swap out the last part of the url with the name of the library you want to debug.
|
In solidjs/solid-styled-components#27, I saw mentioning of running Basically, we need to put the |
We are also evaluating Astro now for SSR at @RapidAPI and this seems a huge blocker, since we rely on |
If you guys can get styled components to work with Astro I am totally going to make the switch. I love styled components, works perfectly with component based styling and makes your code so easy to read. |
vanilla-extract now supports Astro! vanilla-extract-css/vanilla-extract#796 |
I've updated the table with the most recent status. A lot more green now 💚 In addition to official
|
Hey @mayank99 Thanks for this great overview 🙏 Edit: |
@jon301 This is related to the Vanilla Vite plugin itself, same behaviour can be observed in SvelteKit. |
@mayank99 , thank you for great overview and for the Stackblitz examples! I needed to make Astro work with Emotion, because I use Material UI in my website. Even if I've could use also styled-components, the default approach of Emotion seemed interesting to me, pretty simple and no big changes needed. I tried your repo with examples and somehow the workaround for import styledImport, { CreateStyled } from '@emotion/styled';
let styled = typeof styledImport.default !== 'undefined' ? styledImport.default as any as CreateStyled : styledImport; Then I've got it working but with FOUC. Emotion didn't render So my second workaround was to patch There are 3 ways forward for Emotion that I see:
What do you think we should do? |
@igorbt Thanks for looking into this, great work!
So in my repo I'm using a conditional vite config, and it doesn't seem to get the correct values. It works in prod (but not in dev) if I just do this:
This is actually great! I think I tried a variation of this and couldn't get it to work, so I'm happy you were able to. This is better than
I think this would help with styled-components too (as I mentioned earlier). I'm not sure what would be the best way to expose this to users, outside of asking them to make a customized version of the react integration.
I agree, it should be opt-in if astro decides to use @matthewp What do you think? |
It seems advanced approach for Emotion SSR only works with |
For styled-componets situation is almost the same as with emotion - there is no support for new React SSR API Actually React team stated pretty clear that the architectural changes for v18 will make it pretty hard for CSS-in-JS libs to get along: reactwg/react-18#110 and they even advice for "You could however build a CSS-in-JS library that extracts static rules into external files using a compiler". On a more pragmatic note, because Astro mainly uses SSG, the streaming support is not important, and using (deprecated) |
I can confirm that the astro + solid-styled-components (goober solid wrapper) + twin.macro works nicely in both SSR and CSR mode, and also in both dev and prod settings |
@mayank99 if this only requires some config changes I think having this added to the React integration makes sense. |
Well, don't leave us in the dark! How did you set it up? |
Not having great styled-components support is such a deal breaker for astro :( |
90% of my projects use MUI because it's just the best & most complete library out there. |
Would love to see support for MUI as well |
Works like a charm 2023-03-29 Here is some docker help for anyone that needs
|
When should we expect emotion to be fully operational? This is the only problem that stops me from using astro atm |
just a reminder that any "+1"/"ETA?" or similar comments are unhelpful and spammy. if you would like this issue resolved for your use case, the best way to do that is to work with the maintainers of both tools and try to contribute. beyond that, i want to share two things:
|
Emotion works for static site generation (on the ---
import {css} from '@emotion/css'
const tag = css`
border: 1px solid;
`
import {extractCritical} from '@emotion/server'
const mainKey = 'c', key = mainKey + 'ss-'
, className = name => ({
class: name.replace(key, mainKey)
})
---
<style set:html={
extractCritical(
[
tag
]
.join(' ')
)
.css
.replaceAll(
...[
key, mainKey
].map(
value => '.' + value
)
)
}/>
<div {...className(tag)}/> |
Anyone could figure out how to avoid FOUC on Next.js 13, App router, typescript, Twin macros? |
Bro's asking a nextjs question in an astro issue 💀 |
So Emotion definitely works for static site generation (on the index/
|
Hello! import createCache from '@emotion/cache'
import createEmotionServer from '@emotion/server/create-instance'
import * as ReactDOMServer from 'react-dom/server'
import { CacheProvider } from '@emotion/react'
export const extractEmotionCss = (component: () => React.ReactNode) => {
const cache = createCache({ key: 'mui-emotion-cache' })
const { extractCriticalToChunks, constructStyleTagsFromChunks } = createEmotionServer(cache)
const html = ReactDOMServer.renderToString(
<CacheProvider value={cache}>
{component()}
</CacheProvider>,
)
const emotionChunks = extractCriticalToChunks(html)
const emotionCss = constructStyleTagsFromChunks(emotionChunks)
return `${emotionCss} ${html}`
} after this, I have an ---
import { extractEmotionCss } from '../functions/extract-emotion-css';
export interface Props {
component: () => React.ReactNode;
}
const component = Astro.props.component;
const content = extractEmotionCss(component);
---
<Fragment set:html={content} ></Fragment> and with this I can just use it in other astro files, like this: <ExtractEmotionStyles component={MyMuiReactComponent} /> I'm fairly new to Astro and the SSG/SSR stuff, so please tell me if this solution is problematic. |
Mantine has FOUC, have to refresh the page after hyperlink transition for CSS to render. |
@grctest the next Mantine version, v7 currently in alpha, does away with CSS-in-JS altogether and works with Next.js app directory SSR. Upgrading to Mantine v7 when it's out will likely be the best solution going forward. |
Moving this issue to a discussion on our roadmaps repo. |
It's not super clear which CSS-in-JS libraries work, so I'm creating this issue as sort of a place to start the conversation and document the current status.
Here's a few popular libraries that I know about (will keep this list updated):
styled.div is not a function
.Can be worked around with
client:only
or by usingbuildSsrCjsExternalHeuristics
andssr.noExternal
(will cause FOUC).styled.div is not a function
.Can be worked around with
client:only
or by using conditional default import (will cause FOUC). Can also patch@astrojs/react
.Named export 'styled' not found
.Can be worked around using
buildSsrCjsExternalHeuristics
andssr.noExternal
or by downgrading to v3.<style>
tag for SSR needs to be in React componentFrom what I understand, if a library doesn't work in astro, it's because of one or more of these reasons*:
*I could be wrong so would be nice if someone can verify the above points.
Additionally, here's what @FredKSchott would like to see (quote message from discord):
GitHub repo with examples:
https://github.com/mayank99/astro-css-in-js-tests
Participation
The text was updated successfully, but these errors were encountered: