RFC: Global CSS Imports #27953
Replies: 32 comments 44 replies
-
To enable this behavior on the server, does this mean Next.js needs to process all imported dependencies through Webpack (similar to what next-transpile-modules does)? I can imagine that affecting the build performance if enabled by default. |
Beta Was this translation helpful? Give feedback.
-
regarding importing CSS modules from node_modules, the only way I see it useful is together with transpilation of code from node_modules, but even then it might not be worth it. Example:
Transpiling+preprocessing ahead of distribution works fine (it's how all component library do it) BUT you lose all module structure and the build optimizations that could come with it. The other current solution used for this kind of scenario is organising the project and this kind of dependencies in a monorepo, which I guess makes it hard to make the case for this kind of change |
Beta Was this translation helpful? Give feedback.
-
Please, correct me if I'm wrong: currently the behaviour of next.js apps is loading all the css imported in _app.js, no matter if these styles are actually useful for the current/visible component/page? |
Beta Was this translation helpful? Give feedback.
-
Is this limited to only |
Beta Was this translation helpful? Give feedback.
-
My colleague recently made a workaround to make the @yandex/ui library work. Maybe this can help when designing a solution. |
Beta Was this translation helpful? Give feedback.
-
+1 on packages that require this. |
Beta Was this translation helpful? Give feedback.
-
Allow dependencies to import .css/.scss files in the same way CRA (import style globally). This will fix the "Global CSS cannot be imported from within node_modules." error. Technically a feature request, but its related to this. // pages/home.js
import css from "../styles.css"
...
<Stylesheet src={css}/> This will break backwards compatibility, so at start it can we limited to New features this can bring to the Next.js framework.This can introduce new features like allowing css to be global or scoped to a component/page. Scoped styles can be imported (injected as a link or style tag ) when a component is rendered. Possibly allow for dynamic importing of css? Inlining of some or all global css to reduce Cumulative Layout Shift and allow for this effect #12868 (reply in thread) .This can even be useful for something like AMP/hybrid pages where all css can be inlined into You can even introduce ordering of css in the document. This can be useful if you are using something like tailwindcss where // components/Button.js
import css from "../styles/button.stylesheet.css"
...
<Stylesheet scoped order={2} src={css}/>
// pages/_app.js or pages/hello.js
import base from "../styles/base.stylesheet.css"
import utils from "../styles/utils.stylesheet.css"
const Button = dynamic(import('../components/Button'))'
...
<Stylesheet global inline order={1} src={base }/>
<Stylesheet global order={3} src={utils}/>
<Button /> Css order in the document
Css imported by dependencies in AlternativesI know that styled-jsx exits, but it has limitations like no first party support for scss/postcss. And plugins like |
Beta Was this translation helpful? Give feedback.
-
What about styled-components?
That's my go to library, it supports global styles, and it works incredibly
well with the next js, including using full SSR and SSG.
You can even do per components dynamic imports exactly as you described.
I would suggest having a look at what they implemented, and perhaps taking
a few pointers from there at least when it comes to developer friendliness.
…On Tue., Aug. 31, 2021, 5:12 p.m. Jovica Veljković, < ***@***.***> wrote:
Allow dependencies to import .css/.scss files in the same way CRA (import
style globally). This will fix the "Global CSS cannot be imported from
within node_modules." error.
Technically a feature request, but its related to this.
If you are going to be overhauling how CSS is managed in Next.js, why
don`t you introduce a <Stylesheet> component. It can be used in
components/pages for importing any style from the project or node_modules
or even the web (url). This can get rid of "Global CSS cannot be imported
from files other than your 'Custom <App>'" error.
// pages/home.jsimport css from "../styles.css"
...<Stylesheet src={css}/>
This will break backwards compatibility, so at start it can we limited to
*.stylesheet.css and maybe styles from 'node_modules'.
New features this can bring to the Next.js framework.
This can introduce new features like allowing css to be global or scoped
to a component/page. Scoped styles can be imported (injected as a link or
style tag ) when a component is rendered. Possibly allow for dynamic
importing of css?
Inlining of some or all global css to reduce Cumulative Layout Shift and
allow for this effect #12868 (reply in thread)
<#12868 (reply in thread)>
.This can even be useful for something like AMP/hybrid pages where all css
can be inlined into <style amp-custom>.
You can even introduce ordering of css in the document. This can be useful
if you are using something like tailwindcss where @tailwind base must be
at the start, and @tailwind utilities must be at the end of styles.
// components/Button.jsimport css from "../styles/button.stylesheet.css"
...<Stylesheet scoped order={2} src={css}/>
// pages/_app.js or pages/hello.jsimport base from "../styles/base.stylesheet.css"import utils from "../styles/utils.stylesheet.css"const Button = dynamic(import('../components/Button'))'
...
<Stylesheet global inline order={1} src={base }/>
<Stylesheet global order={3} src={utils}/>
<Button />
Css order in the document
1. node_module global styles
2. Ordered <Stylesheet/> styles
2.1 base.stylesheet.css inlined
2.2 button.stylesheet.css, and other styles with order of 2
2.3 utils.stylesheet.css
3. styled-jsx? and css module styles? ( I'm not suggesting to remove
css modules. )
Css imported by dependencies in node_module can be placed before all the
<Stylesheet/> component styles. I don`t know how styled-jsx and css
modules will get ordered, probably after everything.
Alternatives
I know that styled-jsx exits, but it has limitations like no first party
support for scss/postcss. And plugins like styled-jsx-plugin-postcss
don`t have HMR which leads to a bad dev experience. If you use tailwind
with styled-jsx-plugin-postcss, change some file and add some new JIT
style, you need to 1st save the component with the <style jsx> and then
manually refresh the page to see cahges.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#27953 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAOSNPLQLQK4HHJX257UAC3T7VVXPANCNFSM5B57QDTA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
This is a so long-awaited improvement for me. I've got two libraries that are working in a way similar to react-spectrum, where pre-building CSS into a single bundle is not an option as that defeats the purpose of tree-shaking of styles. CSS Modules support with next-transpile-modules support and indeed the last thing that's currently blocking this is support of styles for tag elements. In the description you cover the part about importing the non css modules files. Does that mean that we'll need to move all global styles to a separate file? Currently we're storing them together with other styles in .module.css but this small trade-off shouldn't be causing any tough issues as I see it for the libraries anyways. |
Beta Was this translation helpful? Give feedback.
-
I hope that this would allow global Sass imports as well as CSS—unlike the current allowance for global CSS imports in |
Beta Was this translation helpful? Give feedback.
-
We decided to move separate next.js repos into a monorepo and this issue is a blocker in our case. Any updates on this? Thanks. |
Beta Was this translation helpful? Give feedback.
-
Hi @leerob, hi, @timneutkens, this is still blocking us from using Cypress' component testing feature (cypress-io/cypress#16879) at the moment. Any updates on this? Thanks for taking care of this. |
Beta Was this translation helpful? Give feedback.
-
This would also help us to be able to always use the latest nextjs version. Currently we're importing LESS files globally (on each component) since we have hundreds of components, we can't easily refactor all of them to use css modules. So the restriction of importing global styles is holding us back from using the latest nextjs. I've described more here #29693 Any update on this topic? |
Beta Was this translation helpful? Give feedback.
-
Just a heads up that above is the issue for @nrwl/nx monorepos with next.js app + shared-ui library (as example). |
Beta Was this translation helpful? Give feedback.
-
Was brought here after googling "Global CSS cannot be imported from within node_modules", any workaround in my control to fix this? |
Beta Was this translation helpful? Give feedback.
-
Is there a recommended workaround for now while this RFC gets discussed? |
Beta Was this translation helpful? Give feedback.
-
The solution I temporary implemented was actually by passing the import issue by loading the file as a string
|
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
Is there a good reason this hasn't been acted on yet? I don't see any significant counter-arguments in the thread, just a lot of suggestions and people seeking workarounds because nothing has been done yet. I'd appreciate it if someone could add a warning and some official guidance on the topic to the documentation, so users can at least be aware of this tripping point without having to drag through a bunch of years-old github threads. It's a severe limitation for Next to just be incompatible with a bunch of libraries that every other major build stack can use. I reviewed the official docs and migration guides carefully before deciding to migrate from CRA, yet the first I learned of this issue was several hours into the process when the build stack started choking on a dependency I cannot replace right now. In fact, the FAQ's boast about NextJS' compatibility with 3rd party libraries: I'm not currently paying for this software, so I know I'm not entitled to much, but I would ask that I not be actively misled. |
Beta Was this translation helpful? Give feedback.
-
We’re exploring if a solution to this RFC could be implemented with the Layouts RFC, since they have related pieces (for example, the root layout would replace We will post back here as we learn more 👍🏼 |
Beta Was this translation helpful? Give feedback.
-
I know you don't need someone else saying adding a +1 to the discussion, but this is a major pain point. I'm at the point where I can't un-port my project and this issue is holding me back from using several dependencies that would be very useful to me. Can we allow this behind a configuration flag that is default off? There are no viable work-arounds right now that work with the current next stack (swc), and this is causing a lot of frustration. |
Beta Was this translation helpful? Give feedback.
-
This would help quite a lot. Using next transpile modules substantially increases build time. I’ve been working around this by compiling all my libraries with a modified css plugin. So css (local scope or not) in library’s are emitted as export const locals {} then I use mini-css loader and train it to test css.js files which it already knows that locals is locally scopes styles and default is the string of css. Basically feeding it what css-loader would, but I ship this in my packages to circumvent nexts limitations. |
Beta Was this translation helpful? Give feedback.
-
Slight update here from 12.3 post:
We are exploring this with the upcoming changes! |
Beta Was this translation helpful? Give feedback.
-
I am watching this issue as well. Its such a huge block on my way! |
Beta Was this translation helpful? Give feedback.
-
Watching this as well. |
Beta Was this translation helpful? Give feedback.
-
This is indeed, very frustrating. I really like next.js but this framework should be way, WAY less opinionated on how people can work. Looking forward to seeing this update 😄 |
Beta Was this translation helpful? Give feedback.
-
Update: We’re excited to announce Next.js 13, which includes the new Inside the |
Beta Was this translation helpful? Give feedback.
-
OK. Still blocked when I use Monaco Editor. |
Beta Was this translation helpful? Give feedback.
-
Following up on this: the App Router is now stable with 13.4! CSS files can now be imported inside any layout or page, including styles from external npm packages. |
Beta Was this translation helpful? Give feedback.
-
Goals
node_modules
) to import.css
files that are not CSS Modulesreact-spectrum
which publish JS with CSS importsBackground
When CSS support was first introduced to Next.js, we added some restrictions and conventions to ensure CSS specificity and order would be preserved between compilations and output. These restrictions were added to avoid issues like certain CSS rules overriding each other.
In Next.js, every page is a separate entry point. Pages like
pages/_app.js
are also compiled and added to each page load, since it wraps every page. With webpack 4 the load order is important given that there's no module graph of relationships between entry points.This is why we added the restriction of
pages/_app.js
being the only place you can import global CSS. With webpack 5, the module graph is now aware of which entry points depend on each other, allowing for CSS loading to be handled correctly.We also tried to fix some features made possible by Create React App's handling of CSS. It's possible for a dependency to import global CSS, even though this is not valid JavaScript and can't run in the browser or Node.js environments. We've gotten feedback this restriction is not ideal for all libraries, given that some UI libraries include their own CSS imports (e.g.
react-spectrum
).As of writing this RFC, there are multiple bundlers that have copied the behavior of Create React App with regards to handling CSS. More and more people have started depending on being able to import CSS in
node_modules
, making it harder for them to use these libraries with Next.js.Related Issues and Discussions:
pages/
directory, not just _app #20546Note: We'll likely not add support for
.module.css
as we did not find packages using that. Please provide some examples and we'll have a look if it makes sense.Proposal
In order to integrate these libraries into Next.js applications, we can remove the CSS imports restriction for both
pages
andnode_modules
when webpack 5 is used. This change would allow CSS to still be injected in the right order.One issue that will arise from lifting this restriction is that CSS scoping will become an issue. Previously, you would end up getting guided to using scoped styles (CSS Modules) instead of global styles. This is not a concern for dependencies, as they tend to be published with their own scoped stylesheets.
Advantages
react-spectrum
and others to be used directly in Next.js without any additional configuration.Beta Was this translation helpful? Give feedback.
All reactions