[BUG] CSS in global mode doesn't work in development with JS disabled
Describe the bug CSS Modules don't seem to be server side rendered when experimental css option is set to global as recommended in the documentation.
To Reproduce
- Change the CSS mode to global (e.g.
plugins: [hydrogen({ experimental: { css: 'global' } })]) - Create
example.module.cssfile (e.g.touch example.module.css) - Add some basic styles to the
example.module.cssfile (e.g..red { color: red; }) - Import class from
example.module.cssfile (e.g.import { red } from './example.module.css') - Use imported class on element (e.g.
<span className={red}>Test</span>) - Disable JavaScript on browser
- Load route using
?_botquery parameter
Expected behaviour
A <style> tag containing the CSS for the imported class should be rendered in the <head> and the element with the class should inherit the styles accordingly.
Additional context
This works correctly when the CSS mode is modules-only, but the <style> tag is inlined as described in the documentation below.
https://shopify.dev/custom-storefronts/hydrogen/framework/css-support#css-modules
It also work correctly on the client when JavaScript is enabled.
- Hydrogen version:
1.2.0 - Node version:
16.14.0 - Device details: iMac (macOS Monterey
12.4) - Browser details: Google Chrome
103.0.5060.134
@ramiroazar I assume you are talking about the development server, right? This behavior is actually expected in development because Vite uses JS to inject CSS in order to make HMR work. In production, though, your HTML should contain a link#stylesheet in the head downloading all the styles. Can you confirm it's dev what you are talking about?
Yes, sorry, I forgot to mention this is while using the development server with yarn dev.
I can confirm that building with yarn build or previewing with yarn preview works as expected, thank you.
This is making more sense now, but I don't totally understand why this is expected behaviour?
Other frameworks I've used seem to better reflect the build during development, which is really useful for testing certain things as you go.
These frameworks tend to use Webpack, so not sure if this is a limitation of Vite or more of a framework decision?
It'd be really nice to be able to preview aspects of a build, like SSR, without having to pause development and run a dedicated build.
This is making more sense now, but I don't totally understand why this is expected behaviour?
There's an on going issue with Vite's default behavior when injecting CSS using JS in development. The immediate effect is that there's a CSS flash in development when refreshing a page, but it also affects your use-case.
We should definitely improve this behavior at the Hydrogen level, although we are right now prioritizing other issues. In the meantime, feel free to check this Vite issue and try any of the approaches mentioned there. We will probably use something like that to fix Hydrogen core.