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

Global styles are not inlined in HTML #26

Closed
Destaq opened this issue Oct 18, 2021 · 42 comments
Closed

Global styles are not inlined in HTML #26

Destaq opened this issue Oct 18, 2021 · 42 comments

Comments

@Destaq
Copy link

Destaq commented Oct 18, 2021

Environment


  • Operating System: Darwin
  • Node Version: v14.17.4
  • Nuxt Version: 2.15.8
  • Package Manager: npm
  • Bundler: Webpack
  • User Config: head, css, plugins, bridge, components, buildModules, modules, build
  • Runtime Modules: [email protected], @nuxtjs/[email protected]
  • Build Modules: @nuxt/[email protected]

Describe the bug

TailwindCSS plugins requirements are not being loaded as they should, being run only after the plugin has been rendered. For this specific case, I'm using the TailwindCSS framework which is being enhanced by DaisyUI.

However, there is an initial flicker from TailwindCSS styling to DaisyUI after the page loads. See below recording:

Screen.Recording.2021-10-16.at.11.39.21.AM.mov

I brought up this issue on the DaisyUI repo here: saadeghi/daisyui#249, but the creator noted that it was an issue with a lack of details on Nuxt 3 and Bridge documentation. They provided a working example for Nuxt 3 in addition to that for Nuxt 2, but neither is functional in Bridge.

Reproduction

Modified NuxtJS Bridge example.

Additional context

No response

Logs

No response

@Destaq Destaq added bridge bug Something isn't working labels Oct 18, 2021
@Destaq Destaq changed the title PostCSS plugin requirements load incorrectly (TailwindCSS) TailwindCSS plugin requirements load incorrectl Oct 19, 2021
@Destaq Destaq changed the title TailwindCSS plugin requirements load incorrectl TailwindCSS plugin requirements load incorrectly Oct 20, 2021
@Destaq
Copy link
Author

Destaq commented Oct 20, 2021

I've noticed that if you throw an error inside of nuxtServerInit, as so:

export const actions = {
  async nuxtServerInit({ commit }, { req }) {
    throw new Error('Makes DaisyUI work');
  }
}

However, this obviously isn't a good solution. However, it may help in identifying the problem with Nuxt Bridge.

@Destaq
Copy link
Author

Destaq commented Nov 5, 2021

If you set disable Tailwind's JIT mode, then there is a slightly different result.

Instead of there being a short flicker, the screen freezes on the unrendered, pre-plugin styling, and then styles everything. From there, in-app navigation works without styling issues - this only happens on page loading. This leads me to believe that Tailwind plugin style loading is somehow failing to block the page render.

Screen.Recording.2021-11-05.at.9.32.55.PM.mov

@Destaq
Copy link
Author

Destaq commented Nov 18, 2021

Any chance of this getting addressed anytime soon?

I've been hesitant to continue working with Nuxt Bridge since there's been no fix to this Nuxt-caused issue for the past month.

@lucassimines
Copy link

I'm facing the same issue with Tailwind and Nuxt 3

@Destaq
Copy link
Author

Destaq commented Dec 16, 2021

I'm facing the same issue with Tailwind and Nuxt 3

Have you been able to come up with a solution?

@Tiagogv
Copy link

Tiagogv commented Jan 25, 2022

Any news on this bug?
I figured out that any global styles that you define in the css property on nuxt.config are added to the page by a script and not inlined in the HTML on SSR.

This causes a flicker because the page is first shown without any styles and then the styles are loaded.
This is also true if you generate static pages using nuxi generate using Nuxt Bridge.
I tried to compile tailwindcss using the Tailwind CLI and the using the compiled output on nuxt.config -> Got the same result.

Would be a lot better if the global styles were added inline the same way style defined in the components are added.

@Tiagogv
Copy link

Tiagogv commented Jan 26, 2022

I found a workaround to remove the flickering. Instead of adding the global tailwind css file to nuxt.config css property, I have imported it into my layouts/default.vue file like so:

<style lang="postcss">
@import '@/assets/css/main.css';
</style>

This way the tailwindcss is inlined into the final HTML and not loaded with <link rel="preload">. The only drawback is that your HTML file becomes bigger. However my Lighthouse performance went from a 70 to a 92 because it no longer has a poor CLS score.

If you have more than one layout, you need to add this to every layout.

@danielroe danielroe changed the title TailwindCSS plugin requirements load incorrectly Global styles are not inlined in HTML Jan 26, 2022
@phoenix-ru
Copy link

Adding styles to layouts seems a reasonable workaround, however, it leads to style duplication (even when using sass @use which should theoretically dedupe). Inlining styles from NuxtConfig.css is something we really need

@Blakeinstein
Copy link

Why not add the following to app.vue? instead of layouts?

<style lang="postcss">
@import '@/assets/css/main.css';
</style>

@phoenix-ru
Copy link

Why not add the following to app.vue? instead of layouts?

<style lang="postcss">
@import '@/assets/css/main.css';
</style>

I think the role of app.vue is actually the same as of layouts/default.vue
If not, I would be happy to be wrong

@Blakeinstein
Copy link

I think the role of app.vue is actually the same as of layouts/default.vue

Not really, IIRC app.vue is the application entrypoint, and will be the first to render, any layout would be rendered in the place where is in app.vue

@phoenix-ru
Copy link

I am not really sure, but I think docs need to be updated then to indicate what is the role of app.vue other than replacing a single layout file.

http://v3.nuxtjs.org/docs/directory-structure/layouts

@Blakeinstein
Copy link

Blakeinstein commented Feb 2, 2022

I still dont think adding critical css files in app.vue is still the way to go. It results in a poor lighthouse score (as this is claimed to be bad js) and has partially resulted in this somehow? FortAwesome/vue-fontawesome#342

Which is also the reason behind an initial flicker. when markup is loaded but the css is loaded when js executes.

A critical problem lies here because the vite bundler doesnt support dynamic glob imports (in the style of nuxt2)

Edit: I clearly missed the bridge tag on this issue, but this seems to occur on nuxt3 with vue3 too

@phoenix-ru
Copy link

The flicker issue (on webpack at least) is related to the missing SSR critical CSS collection in vue-loader v16.
I have managed to work around this by using a fork which adds naive inlining: https://github.com/phoenix-ru/vue-loader. I've written it for Vue 3 SSR but turns out that this also works for Nuxt 3.
The Bridge works without any FOUCs though.

@Blakeinstein
Copy link

turns out that this also works for Nuxt 3.

Can you explain usage?

@phoenix-ru
Copy link

You need to install the packaged tarball in place of vue-loader and check that npm resolves to the patch.

npm i -D vue-loader@https://github.com/phoenix-ru/vue-loader/releases/download/critical-css/vue-loader.tgz

npm ls vue-loader

Beware that this patch only works for webpack (config.vite=false) and may introduce style duplication with Nuxt (or may not)

You can check the source code at https://github.com/phoenix-ru/vue-loader/tree/critical-css. Sorry for an inconvenient structure, this is a dirty patch and I had no time to update it for a merge request.

@Blakeinstein
Copy link

npm ls vue-loader
├─┬ [email protected] invalid: "latest" from the root project
│ └─┬ @nuxt/webpack-builder@npm:@nuxt/[email protected]
│   └── [email protected]
└── [email protected] invalid: "https://github.com/phoenix-ru/vue-loader/releases/download/critical-css/vue-loader.tgz" from the root project

npm ERR! code ELSPROBLEMS

still good? I am using yarn and add this as a dependency instead of a dev dependency

@phoenix-ru
Copy link

npm ls vue-loader
├─┬ [email protected] invalid: "latest" from the root project
│ └─┬ @nuxt/webpack-builder@npm:@nuxt/[email protected]
│   └── [email protected]
└── [email protected] invalid: "https://github.com/phoenix-ru/vue-loader/releases/download/critical-css/vue-loader.tgz" from the root project

npm ERR! code ELSPROBLEMS

still good? I am using yarn and add this as a dependency instead of a dev dependency

Seems like Nuxt has updated the loader to v17. I guess you could still use it?..

@Blakeinstein
Copy link

Seems like Nuxt has updated the loader to v17. I guess you could still use it?..

Doesnt seem like it. Additionally, I cant even import things like windi-css which use virtual to mount css (which cannot be resolved in a style context). Proper style resolution is the only thing, as far as I can see that is stopping nuxt3 from being used in production, mainly because of the weird initial flicker that visitors experience.

@Blakeinstein
Copy link

I am not really sure, but I think docs need to be updated then to indicate what is the role of app.vue other than replacing a single layout file.

The docs apparently do suggest the same, https://v3.nuxtjs.org/docs/directory-structure/app

Remember that app.vue acts as the main component of your Nuxt application. Anything you add in it (JS and CSS) will be global and included in every page.

@phoenix-ru
Copy link

I cant even import things like windi-css which use virtual to mount css

Could you elaborate more on that please?

The patch I did is naive and works by providing the styles from the SFC to the SSR context in a beforeCreate hook via importing the SFC dependencies. It was initially developed to overcome the FOUC when loading modules through Webpack 5 Module Federation.

Note that it does not really inject the styles, as that is done by Nuxt, but only provide them to the context (and that's the reason I assume that I move in the right direction). The critical CSS collection is tricky and hasn't been solved since the introduction of vue-loader v16.

I know that windicss uses JIT-like compilation, but I haven't checked their webpack implementation (https://github.com/windicss/windicss-webpack-plugin).

I'd really like to contribute to Nuxt and to Vue renderer in general by solving this problem because we already invested a big chunk of time and resources and seeing Nuxt introduce breaking changes is something we really want to avoid.

P.S. I have no information about the Vite implementation and will not be looking there.

@shldhee
Copy link

shldhee commented Mar 4, 2022

When will it be resolved??

@n4an
Copy link

n4an commented Apr 11, 2022

When will it be resolved??

In october 2021 i used i think

  // build: {
  //   optimization: {
  //     runtimeChunk: true,
  //     splitChunks: {
  //       maxSize: 240000,
  //       name: true,
  //       cacheGroups: {
  //         styles: {
  //           name: 'styles',
  //           test: /\.(css|vue)$/,
  //           chunks: 'all',
  //           enforce: true
  //         }
  //       }
  //     }
  //   }
  // },

@danielroe danielroe transferred this issue from nuxt/framework Apr 13, 2022
@Torgian
Copy link

Torgian commented Apr 14, 2022

I've tried quite a few different things to try to resolve this issue on my own project;

  1. Add the css file in an app.vue file
  2. Add the css to the default.vue layout
  3. Import it in the style block
  4. Original css import in Nuxt.config did not seem to work

Basically, css seemed to work fine in nuxtjs. But, after adding Nuxt Bridge, we get that flash of un-styled pages when doing a hard refresh of the browser.

Haven't found a solution. Pretty much stuck at this point.

@phoenix-ru
Copy link

phoenix-ru commented Apr 14, 2022

I've tried quite a few different things to try to resolve this issue on my own project;

Hi, in my setup everything works fine when adding it via SCSS to layouts/default.vue and all other layout files (Nuxt Bridge):

<style lang="scss">
@use './my_styles.css';
</style>

@Torgian
Copy link

Torgian commented May 18, 2022

I've tried quite a few different things to try to resolve this issue on my own project;

Hi, in my setup everything works fine when adding it via SCSS to layouts/default.vue and all other layout files (Nuxt Bridge):

<style lang="scss">
@use './my_styles.css';
</style>

Thanks for the reply, but this did nothing for me. I even tried setting the styles directly in the default.vue file for my default layout, but this also did nothing. It has something to do with processing the style and setting it before the screen renders. This has never been a problem before attempting to update to bridge.

As it is, this, as well as an issue with nuxt auth compatibility makes bridge a non-starter for our app.

@patrickalima98
Copy link

I've tried quite a few different things to try to resolve this issue on my own project;

Hi, in my setup everything works fine when adding it via SCSS to layouts/default.vue and all other layout files (Nuxt Bridge):

<style lang="scss">
@use './my_styles.css';
</style>

HI, this works for me, but I get a new error when my CSS is from my node_modules with relative paths for font-files, like the bellow screenshot.

image

@phoenix-ru
Copy link

I've tried quite a few different things to try to resolve this issue on my own project;

Hi, in my setup everything works fine when adding it via SCSS to layouts/default.vue and all other layout files (Nuxt Bridge):

<style lang="scss">
@use './my_styles.css';
</style>

HI, this works for me, but I get a new error when my CSS is from my node_modules with relative paths for font-files, like the bellow screenshot.

image

This is not related to the topic, but I had the same issue.
If that is your library, make sure you either set webpack's publicPath to the name of your library (e.g. publicPath: '@yourscope/yourlib') or you do a construction like this:

// your_library.scss
$module-path: '@' !default; // or any alias to project root

// same file, in your font-face definition
src: url(#{$module-path}/path/to/font)

// when consuming (e.g. in nuxt)
@use '@yourscope/yourlib/your_library.scss' with (
  $module-path: '@yourscope/yourlib'
);

@justindasilva
Copy link

@pi0 Any ideas for us on this one?
Whenever I do a hard refresh, I get about a second of the app being unstyled. Wondering what the solution might be.

@justindasilva
Copy link

My solution for now was to remove this from my nuxt.config.ts

css: [
    `~/assets/scss/index.scss`,
  ],

And add this to my layouts/default.vue

<style lang="scss">
@import '~/assets/scss/index.scss';
</style>

@azelalynetan
Copy link

@justindasilva I have the same issue. I tried your solution but it didn't worked for me. I'm still seeing my app being unstyled for a second after hard refresh. I'm using nuxt bridge with tailwind.

Do you have or does anyone have a suggestion or workaround for this?

@enkot
Copy link

enkot commented Aug 18, 2022

I also have this issue, but when disable nitro - it works fine (inlines css in SSR):

export default defineNuxtConfig({
  ...
  bridge: {
    nitro: false,
  }
})

@azelalynetan
Copy link

I tried disabling the nitro and it works. I no longer encountered unstyled components for a second after reloading the page. Is there other way to fix it without disabling the nitro?

@AndrewBogdanovTSS
Copy link

Disabling nitro is not the solution as well as placing CSS in layouts, all of that are dirty workarounds. Nuxt Bridge should support it's default feature of referencing CSS files in nuxt config.

@AndrewBogdanovTSS
Copy link

@danielroe any ETA for this fix? Could it be prioritized for RC11 ?

@danielroe
Copy link
Member

Just looking into this, I can't reproduce - in production - with the following config:

import { defineNuxtConfig } from '@nuxt/bridge'

export default defineNuxtConfig({
  bridge: {
    nitro: true,
    vite: false
  },
})

Note that:

  1. I can reproduce with vite enabled (as it is by default), as vite currently does not have support for inlining styles
  2. I can reproduce in development mode with webpack

@AndrewBogdanovTSS
Copy link

AndrewBogdanovTSS commented Sep 24, 2022

@danielroe yes, that's correct, the issue is reproducible only in development mode with Webpack, but it has to work the same as in production, right?

@AndrewBogdanovTSS
Copy link

@danielroe is there any issue where I could track progress on adding inline styles for Vite?

@maxarias-io
Copy link

maxarias-io commented Dec 9, 2022

This still seems to be an issue on Bridge 3.0.0-27833237.ddd8ecc with Nitro(nuxi), running yarn build && yarn start

Even with this config: #26 (comment)

Copy link
Contributor

github-actions bot commented Apr 4, 2024

Would you be able to provide a reproduction? 🙏

More info

Why do I need to provide a reproduction?

Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.

What will happen?

If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritise it based on its severity and how many people we think it might affect.

If needs reproduction labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.

How can I create a reproduction?

We have a couple of templates for starting with a minimal reproduction:

👉 https://stackblitz.com/github/nuxt/starter/tree/v2-bridge
👉 https://codesandbox.io/p/github/nuxt/starter/v2-bridge-codesandbox

A public GitHub repository is also perfect. 👌

Please ensure that the reproduction is as minimal as possible. See more details in our guide.

You might also find these other articles interesting and/or helpful:

Copy link
Contributor

This issue was closed because it was open for 7 days without a reproduction.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests