Closed numso closed 1 year ago
I've made an example how it could be done (also avoiding double rendering; didn't think into it too much though, probably not an optimal solution), but the last issue with non-matching classes requires something similar to babel-plugin-styled-components, I think.
https://gist.github.com/alexkuz/d91c9ce1380f4b528ebf262ad0e4f959
Running into similar problems. Hopefully a solution can be found soon, as styled component support is a must for me!
add babel-plugin-styled-components as dev dependency.
add customer babel.config.js like blow
module.exports = { presets: [ "@remix-run/core/babel", ], plugins: [ [ "babel-plugin-styled-components", { "ssr": true } ] ] };
this work for me
@AIEPhoenix I'm still seeing FOUC even with this added as a dev dependency. Is this something you don't see?
I am getting this from a fresh remix install, not CSS or anything added to it.
@AIEPhoenix Your suggestion has zero effect for me. Looking through the source and then finding this closed issue for implementing being able to do this seems to backs up it is not implemented? Issue #36
Ultimately it is what is needed though so that class names stay consist across the server and client.
https://styled-components.com/docs/advanced#tooling-setup
In order to reliably perform server side rendering and have the client side bundle pick up without issues, you'll need to use our babel plugin. It prevents checksum mismatches by adding a deterministic ID to each styled component.
I'm sure enabling us to use/configure Babel would help a lot of people with a lot of issues π
I know Remix do not want to "lock in" to things (so they can swap out esbuild later if needed etc) but there's so many tools we can't use as things stand now π (#717)
I appreciate and like their take too with how they recommend to do styling (and I have really had a good go at doing it that way!) but at work I work day in day out with styled-components so that's where my mind and workflow is most efficient.
The styled-components example that was recently added to the dev branch worked well for me: https://github.com/remix-run/remix/tree/1576615c0bdb6222bcddf0ffefe19d2335169299/examples/styled-components
The hydration warning is still present. It looks like the plan is for styled-components to support SSR without needing the babel-plugin. That's being tracked here: https://github.com/styled-components/styled-components/issues/3660
Still no solution for this? @numso I tried following the example you shared but I still get the same error. and besides, it's no different from what I already have in mine.
And I think before they work on styled-components supporting SSR without the babel-plugin they should work on making the babel-plugin work in remix.
Because in next.js there it's just an easy setup with .babelrc, but it's not the case in remix. I don't know if it's already possible in remix some other way, but I have searched all around but no solution.
And the error I get is something like Warning: Prop 'className' did not match. Server: "sc-fFeiMQ chKvQT" Client: "sc-gsDKAQ fVbgCo"
I have a somewhat working solution for hydration issue, although I'm not ready to make it public yet. It monkey-patches Remix's esbuild to add a custom plugin which then uses tree-sitter
(a fast code parser that supports TS) to parse the source and add component config, same way as styled-components/macro
does.
For now it only supports styled.tag
and styled(...)
(which are the most common usecases I believe).
Gonna test it more and share it later.
The styled-components example that was recently added to the dev branch worked well for me: https://github.com/remix-run/remix/tree/1576615c0bdb6222bcddf0ffefe19d2335169299/examples/styled-components
The hydration warning is still present. It looks like the plan is for styled-components to support SSR without needing the babel-plugin. That's being tracked here: styled-components/styled-components#3660
So we're currently running into an issue with this solution. It works, until we hit a 404 page. The 404 page will be styled, but once we navigate away, our CSS will not be loaded anymore.
Edit: Bit of searching leads me here: https://github.com/mui/material-ui/issues/30436
I have a somewhat working solution for hydration issue, although I'm not ready to make it public yet. It monkey-patches Remix's esbuild to add a custom plugin which then uses
tree-sitter
(a fast code parser that supports TS) to parse the source and add component config, same way asstyled-components/macro
does. For now it only supportsstyled.tag
andstyled(...)
(which are the most common usecases I believe). Gonna test it more and share it later.
Any news on that? I'm still having issues to make styled-components
work correctly without the babel-plugin
and I'm almost sure that the componentId
issue is causing it.
If I have any styled-component with a chunk of css that is not rendered on the server due some react state and on the client this state is changed, it seems styled-components recalculate some componentId
s and recreate the CSS classes for those specific components, leaving its children with the original classes that came from the server.
This is happening on a private repo, but I'll try to reproduce it and add an example here.
@prxg22 I could publish it this weekend I think, it works for us so far. It would be helpful to look at your example to see if it would help in your case.
@alexkuz it happens that digging more I found that what I described only happens with components from our ui-component lib and only if we extend them on styled-components
like:
const Nav = styled.nav(({ isMenuOpen }) => `
${Button} {
// some css
}
${isMenuOpen && css`
${Button} {
// after menu opens Nav gets a new CSS class, Button doesn't
}
`}
`)
if we create a new styled-component (eg. styled(Button)(({isMenuOpen}) => ...)
) and generate on the server as the remix example, it works perfectly.
Interesting. I tried to recreate your example and it still doesn't work with my plugin, but if it's written like this, it works fine:
const Nav = styled.nav`
${Button} {
// some css
}
${p => p.isMenuOpen && css`
${Button} {
// after menu opens Nav gets a new CSS class, Button doesn't
}
`}
`;
I fixed my problem by building our component lib using babel-plugin-styled-components
adding the ssr
and namespace
options
@prxg22 just realized there was css
missing in your example, that's why it didn't work for me:
const Nav = styled.nav(({ isMenuOpen }) => css`
...
@prxg22 do you mind sharing with us how you fixed it with babel-plugin-styled-components
Sorry, @alexkuz, my bad π
@Elijah-trillionz as I said, it was not a fix on the remix app.
We are using an ui component lib, which is built using babel.
I just add the following line to its babel.config.json
:
module.exports = {
...,
plugins: [
...,
['babel-plugin-styled-components', { ssr: true, namespace: 'some_namespace' }],
],
}
@prxg22 ok thanks for the clarification
I've published my plugin, try it out:
https://github.com/lukalabs/lukalabs-npm/tree/main/packages/esbuild-inject-plugin https://github.com/lukalabs/lukalabs-npm/tree/main/packages/esbuild-styled-components
If you have any issues please let me know.
@prxg22 fyi
@alexkuz I am having issues installing esbuild-styled-components. It keeps throwing npm errors. It seems to fail when it's about to install node-gyp. Should I paste the error logs here or create an issue on the package repo?
Chat me on Whatsapp+2347026260392
On Mon, May 9, 2022, 7:39 PM Elijah Trillionz @.***> wrote:
@alexkuz https://github.com/alexkuz I am having issues installing esbuild-styled-components https://github.com/lukalabs/lukalabs-npm/tree/main/packages/esbuild-styled-components. It keeps throwing npm errors. Should I paste the error logs here or create an issue on the package repo?
β Reply to this email directly, view it on GitHub https://github.com/remix-run/remix/issues/1032#issuecomment-1121445294, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZCCBUQKWRXF7LF2ABU7CMDVJFLVJANCNFSM5J72OP6Q . You are receiving this because you are subscribed to this thread.Message ID: @.***>
@Elijah-trillionz you may need to upgrade you Node. Try to find a similar issue on https://github.com/tree-sitter/tree-sitter, that's probably where it comes from.
@alexkuz Gets rid of errors on dev and production, thanks!
I can't get any of this to work :(
I've opened a PR to the Remix examples repo that addresses hydration errors: https://github.com/remix-run/examples/pull/311.
As others mentioned, the trick is to run your styled components through the Babel CLI first using babel-plugin-styled-components and then importing the generated JS into your Remix app. It's a bit clunky but this is similar to how many other tools are currently supported in Remix (e.g. Sass).
Which Remix packages are impacted?
@remix-run/react
What version of Remix are you using?
1.0.6
What version of Node are you using? Minimum supported version is 14.
14
Steps to Reproduce
https://codesandbox.io/s/remix-styled-bug-repro-5sv6v
Expected Behavior
The client should hydrate the styles from styled-component without errors.
Actual Behavior
The style tag and all the style rules flash onto the screen as plain text before the javascript kicks in and removes them, applying the correct styles. Some content is also duplicated on the page (in the codesandbox above it is the footer). We also see an error in the console:
Expected server HTML to contain a matching <link> in <head>
.Looks like the docs have you run
const styles = sheet.getStyleTags()
which returns a string. When react renders this string it html encodes it so you end up with a string in your head instead of a style tag.Switching that to
const styles = sheet.getStyleElement()
causes the page to server render the correct styles. But as soon as js kicks in it removes those styles and throws this in the console:Warning: Did not expect server HTML to contain a <style> in <head>
If you instead gather up the styles and markup in a single render, and then inject the styles as a string:
markup.replace('</head>', styles + '</head>')
things seems to work better but it still throws this warning in the console:Warning: Prop 'className' did not match. Server: "sc-fFeiMQ chKvQT" Client: "sc-gsDKAQ fVbgCo"