Skip to content
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

Styled-components + next.js + 'use client' #4025

Open
MrOxMasTer opened this issue May 28, 2023 · 22 comments
Open

Styled-components + next.js + 'use client' #4025

MrOxMasTer opened this issue May 28, 2023 · 22 comments

Comments

@MrOxMasTer
Copy link

Hello. I don't understand. Maybe it's some kind of mistake? Why should I write 'use client' every time I use styled-components?

I may understand that next.js does not support context or elements from libraries in the "styled" example. But just explain 2 things to me.

  1. Why if we write 'use client' in the component, then it does not apply to all components. Isn't that how it's supposed to work? According to the next documentation.js is how it should work, that the component above also acts on the lower elements.

image

  1. What's the point of using next.js if I need to register 'use client' almost everywhere. Is this the next thing.js? With Styled-components, almost all my components become client-side and it makes sense to use next.js disappears.
@charset404
Copy link

Only the scope within the file where 'use client' was used will be rendered on the client-side.

Example: If the index.js component contains 'use client' at the top, it will be rendered on the client-side. If the index.js component contains another component within it, that component will also be rendered on the client-side.

Now, if you use the index.js component (on the client-side) within a server-side component, the index.js component will remain on the client-side, and the server-side component will stay on the server-side.

It's frustrating to have to keep declaring 'use client'. The thing is, we're waiting for someone to innovate with a CSS-in-JS solution that handles SSR. I believe some libraries will die because they don't know how to deal with this.

Next.js has other advantages besides server-side rendering, such as easily creating error pages, loading components, layouts, structure, built-in compiler, image optimizer, and many more. These are just some of the basic things. Take a look at the documentation for more details.

@MrOxMasTer
Copy link
Author

It's frustrating to have to keep declaring 'use client'. The thing is, we're waiting for someone to innovate with a CSS-in-JS solution that handles SSR. I believe some libraries will die because they don't know how to deal with this.

I understand that next.js is a very cool technology, which is famous not only for server rendering. I love styled components very much, but the problem is that I have to prescribe 'use client' everywhere and prescribe it - this is not the main problem. The problem arises in the fact that I have practically no server components at all, because SC is used for each and everywhere you need to prescribe 'use client' and because of this the main meaning is lost next.js . It's just that optimization is important to me, and such a breakthrough technology as server rendering helps to optimize your application very well, and when you have to turn all components into client components everywhere, then the meaning is lost. I really hope that you will come up with something with the developers next.js

@aspirisen
Copy link
Contributor

I also used styled-components, but when server components have come it became not so smooth in terms of DX. I had a UI library and everywhere where I create styled component I had to put 'use client' (or just to index.js file). However, you do not need to put 'use client' in server components where you just consume the component from UI kit.

So my approach was just to extract all styled components into separate files, mark them as 'use client' and then I can freely use them in server components because you can insert client components into server components. But there was a problem with as prop. If you will try to pass some component to as prop in server file you will get an error because you can't pass functions from server component to client component, so you had to create another file just for that part of JSX. Eventually I just gave up and switched to zero runtime style libraries.

and such a breakthrough technology as server rendering helps to optimize your application very well,

@MrOxMasTer Even with 'use client' you still have server side rendering, so there is no downgrade from "pages" approach

As I understand the core problem is that styled components use context, which is not supported on server side

@MrOxMasTer
Copy link
Author

I also used styled-components, but when server components have come it became not so smooth in terms of DX. I had a UI library and everywhere where I create styled component I had to put 'use client' (or just to index.js file). However, you do not need to put 'use client' in server components where you just consume the component from UI kit.

So my approach was just to extract all styled components into separate files, mark them as 'use client' and then I can freely use them in server components because you can insert client components into server components. But there was a problem with as prop. If you will try to pass some component to as prop in server file you will get an error because you can't pass functions from server component to client component, so you had to create another file just for that part of JSX. Eventually I just gave up and switched to zero runtime style libraries.

and such a breakthrough technology as server rendering helps to optimize your application very well,

@MrOxMasTer Even with 'use client' you still have server side rendering, so there is no downgrade from "pages" approach

As I understand the core problem is that styled components use context, which is not supported on server side

The problem of extracting to a separate file will not help. The components are rendered on the client side anyway and I have almost any element, the shell is SC.

Server rendering is minimal because yes, SC uses a context that does not support server rendering

And what do you use for zero-style libraries. Something like talewind CSS?

@MrOxMasTer
Copy link
Author

I also used styled-components, but when server components have come it became not so smooth in terms of DX. I had a UI library and everywhere where I create styled component I had to put 'use client' (or just to index.js file). However, you do not need to put 'use client' in server components where you just consume the component from UI kit.

So my approach was just to extract all styled components into separate files, mark them as 'use client' and then I can freely use them in server components because you can insert client components into server components. But there was a problem with as prop. If you will try to pass some component to as prop in server file you will get an error because you can't pass functions from server component to client component, so you had to create another file just for that part of JSX. Eventually I just gave up and switched to zero runtime style libraries.

and such a breakthrough technology as server rendering helps to optimize your application very well,

@MrOxMasTer Even with 'use client' you still have server side rendering, so there is no downgrade from "pages" approach

As I understand the core problem is that styled components use context, which is not supported on server side

It seems to me that the emotion library for styles does not require a 'use client'. Do you know anything about this?

@aspirisen
Copy link
Contributor

Server rendering is minimal because yes, SC uses a context that does not support server rendering

I do not understand it clearly. If you have styled component it still be rendered on server side (SSR). So if you will open HTML source of your page you will see html layout from use client components as well. Yes, you will have hydration procedure like with every SSR, but for initial request you will get everything from server and client components. You can try to disable javascript on the page and then refresh it.

It seems to me that the emotion library for styles does not require a 'use client'.

Unfortunately no, I haven't used emotion

@MrOxMasTer
Copy link
Author

Server rendering is minimal because yes, SC uses a context that does not support server rendering

I do not understand it clearly. If you have styled component it still be rendered on server side (SSR). So if you will open HTML source of your page you will see html layout from use client components as well. Yes, you will have hydration procedure like with every SSR, but for initial request you will get everything from server and client components. You can try to disable javascript on the page and then refresh it.

It seems to me that the emotion library for styles does not require a 'use client'.

Unfortunately no, I haven't used emotion

And what libraries do you use for the c style next.js ?

@aspirisen
Copy link
Contributor

Currently I use https://vanilla-extract.style/

@MrOxMasTer
Copy link
Author

Server rendering is minimal because yes, SC uses a context that does not support server rendering

I do not understand it clearly. If you have styled component it still be rendered on server side (SSR). So if you will open HTML source of your page you will see html layout from use client components as well. Yes, you will have hydration procedure like with every SSR, but for initial request you will get everything from server and client components. You can try to disable javascript on the page and then refresh it.

It seems to me that the emotion library for styles does not require a 'use client'.

Unfortunately no, I haven't used emotion

I just can't figure out the only thing. I don't know much about SSR and how SC works with it, and that's the question. Does it make sense to use server rendering when using SC, if we prescribe 'use client' everywhere

@aspirisen
Copy link
Contributor

If you add 'use client' you still have server side rendering, even for styled components.

https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive

Components in the Client Component module graph are primarily rendered on the client, but with Next.js, they can also be pre-rendered on the server and hydrated on the client.

@MrOxMasTer
Copy link
Author

If you add 'use client' you still have server side rendering, even for styled components.

https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive

Components in the Client Component module graph are primarily rendered on the client, but with Next.js, they can also be pre-rendered on the server and hydrated on the client.

that is, it turns out that both client and server components are rendered on the server. Then it turns out that the server components just continue to be rendered on the server after the page is rendered?

@MrOxMasTer
Copy link
Author

If you add 'use client' you still have server side rendering, even for styled components.

https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive

Components in the Client Component module graph are primarily rendered on the client, but with Next.js, they can also be pre-rendered on the server and hydrated on the client.

Just for example, if I replace everything with tailwind CSS and in my opinion it does not require 'use client', then this will be a more optimized solution if viewed from the point of view of NOT implementing the technology (SC is written in context and other), but from the Next js. That is, do I lose something in performance if I use SC, instead of tailwind SS (if we do not take into account that SC itself is a loading technology, but take into account SSR and other things related to next.js )

@aspirisen
Copy link
Contributor

In that terms - yes. Because in case of SSR ('use client') your component is executed twice - first on server and second one on client. Also, everything you import in client files will be added to bundle (if you import something in server files they are not included in browser bundle and hence do not send to client)

@MrOxMasTer
Copy link
Author

In that terms - yes. Because in case of SSR ('use client') your component is executed twice - first on server and second one on client. Also, everything you import in client files will be added to bundle (if you import something in server files they are not included in browser bundle and hence do not send to client)

It's a shame, now I'm looking for a replacement for SC, although I really liked the library, but I read a lot and saw how people write that it is heavy in itself

@charset404
Copy link

In that terms - yes. Because in case of SSR ('use client') your component is executed twice - first on server and second one on client. Also, everything you import in client files will be added to bundle (if you import something in server files they are not included in browser bundle and hence do not send to client)

It's a shame, now I'm looking for a replacement for SC, although I really liked the library, but I read a lot and saw how people write that it is heavy in itself

You currently have five options, and I have tested various libraries to reach these conclusions:

  1. "Give up" on Next.js SSR and use vanilla-extract: While this means sacrificing SSR, it offers an improvement over plain CSS. (This is the option I am currently using.)

  2. Embrace SSR and use a library called Tailwind CSS, which may be considered "pollution" as it moves you away from pure CSS, potentially slowing down your learning process.

  3. Embrace SSR and utilize module.css in combination with SASS.

  4. Embrace SSR and use module.css exclusively.

  5. You can give up on Next.js and explore alternative frameworks that offer similar functionality without deviating from the context. However, personally, I choose to stick with Next.js because my team is already using it. In a team environment, it can be challenging to convince everyone to switch frameworks, so it's often more practical to work within the existing framework.

@Jacksonmills
Copy link

In that terms - yes. Because in case of SSR ('use client') your component is executed twice - first on server and second one on client. Also, everything you import in client files will be added to bundle (if you import something in server files they are not included in browser bundle and hence do not send to client)

It's a shame, now I'm looking for a replacement for SC, although I really liked the library, but I read a lot and saw how people write that it is heavy in itself

You currently have five options, and I have tested various libraries to reach these conclusions:

1. "Give up" on Next.js SSR and use vanilla-extract: While this means sacrificing SSR, it offers an improvement over plain CSS. (This is the option I am currently using.)

2. Embrace SSR and use a library called Tailwind CSS, which may be considered "pollution" as it moves you away from pure CSS, potentially slowing down your learning process.

3. Embrace SSR and utilize module.css in combination with SASS.

4. Embrace SSR and use module.css exclusively.

5. You can give up on Next.js and explore alternative frameworks that offer similar functionality without deviating from the context. However, personally, I choose to stick with Next.js because my team is already using it. In a team environment, it can be challenging to convince everyone to switch frameworks, so it's often more practical to work within the existing framework.

I went with 2. Tailwind has been pretty nice, but will be keeping my eye on this issue for sure!

@matheusrgarcia
Copy link

In that terms - yes. Because in case of SSR ('use client') your component is executed twice - first on server and second one on client. Also, everything you import in client files will be added to bundle (if you import something in server files they are not included in browser bundle and hence do not send to client)

It's a shame, now I'm looking for a replacement for SC, although I really liked the library, but I read a lot and saw how people write that it is heavy in itself

You currently have five options, and I have tested various libraries to reach these conclusions:

  1. "Give up" on Next.js SSR and use vanilla-extract: While this means sacrificing SSR, it offers an improvement over plain CSS. (This is the option I am currently using.)
  2. Embrace SSR and use a library called Tailwind CSS, which may be considered "pollution" as it moves you away from pure CSS, potentially slowing down your learning process.
  3. Embrace SSR and utilize module.css in combination with SASS.
  4. Embrace SSR and use module.css exclusively.
  5. You can give up on Next.js and explore alternative frameworks that offer similar functionality without deviating from the context. However, personally, I choose to stick with Next.js because my team is already using it. In a team environment, it can be challenging to convince everyone to switch frameworks, so it's often more practical to work within the existing framework.

SSR works fine with Styled Components, only Server Components are not supported yet, which are two completely different things

@Fusseldieb
Copy link

As someone who is coming from Vue, this is extremely confusing.

@doksara
Copy link

doksara commented Nov 16, 2023

Is this fixed? Do I really have to write 'use client' on each of my 432 styles.ts files?

@aberba
Copy link

aberba commented Dec 30, 2023

@doksara Yes. It a pain to use styled-components in Next.Js now. I'm looking into using vanilla-extract for new projects henceforth

@TheRealsz
Copy link

Could someone inform me whether using styled components to style all my pages and components will have any impact on my SEO? I'm currently working on an e-commerce app and aim to prioritize SSR whenever feasible because of SEO.

@jackherizsmith
Copy link

Could someone inform me whether using styled components to style all my pages and components will have any impact on my SEO? I'm currently working on an e-commerce app and aim to prioritize SSR whenever feasible because of SEO.

SEO would only be effected by page load time, which styled components will have a minor impact on since it injects the CSS at run time (but negligible, really, compared to the value of your pages to users' keywords and their relevance to the site structure you share with web crawlers via sitemaps). I recommend installing Screaming Frog to help you analyse your SEO, including impact of your changes over time.

The bigger problem you'll have is making SC work with SSR, a topic which is covered extensively by every comment in this thread prior to yours.

As for me I can't stand Tailwind so I guess it's back to basics, CSS all the way 🚀 (until SC can somehow resolve this challenging problem)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants