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

Svelte SSR does not render component CSS #1760

Closed
buhrmi opened this issue Dec 26, 2023 · 10 comments
Closed

Svelte SSR does not render component CSS #1760

buhrmi opened this issue Dec 26, 2023 · 10 comments
Assignees
Labels
svelte Related to the svelte adapter

Comments

@buhrmi
Copy link
Contributor

buhrmi commented Dec 26, 2023

Version:

  • @inertiajs/svelte version: 1.0.14

Describe the problem:

When using Svelte SSR, the server side renderer does not render the component CSS, which results in content shifting around once the CSS is loaded via Javascript.

@buhrmi buhrmi added the svelte Related to the svelte adapter label Dec 26, 2023
buhrmi added a commit to buhrmi/inertiax that referenced this issue Dec 26, 2023
buhrmi added a commit to buhrmi/inertiax that referenced this issue Jan 17, 2024
include component CSS in head, fixes inertiajs#1760
@buhrmi
Copy link
Contributor Author

buhrmi commented Mar 3, 2024

there is a PR #1761

@buhrmi
Copy link
Contributor Author

buhrmi commented Jun 20, 2024

We should start brainstorming how this can be fixed for Svelte 5. Since Svelte 5's component.render() call does not return css anymore, we have to find that CSS in other places. One place where we can look is Vite's manifest.json file. If we had a list of module IDs that are being used during the render call, we could look up all the CSS files in the manifest and include this in the <head>. There is an example in the Vite docs how to do this with VueServerRenderer: https://vitejs.dev/guide/ssr#generating-preload-directives
Unfortunately, I can't find a way to get a list of the module IDs with Svelte's render function. I know there must be a way since obviously frameworks exist that support Svelte SSR (SvelteKit, etc.). If anybody can help take a look, would be awesome.

@buhrmi
Copy link
Contributor Author

buhrmi commented Sep 13, 2024

If anyone is in a position like me and wants to preload the CSS when using SSR with Svelte 5, here is what I'm currently doing:

  1. Disable the cssCodeSplit config option in Vite. This will put all emitted CSS in one file.
  2. In your backend adapter, open up the generated manifest.json file (usually in public/vite/.vite/manifest.json).
  3. In this file look for the style.css entry.
  4. Add a link to that file in your <head>

Here's an example for Rails:

  def vite_global_style_tag
    if Rails.env.test?
      vite_folder = "vite-test"
    else
      vite_folder = "vite"
    end

    manifest_path = Rails.root.join("public", vite_folder, ".vite", "manifest.json")
    return "" unless File.exist?(manifest_path)
    manifest = JSON.parse(File.read(manifest_path))
    file = manifest["style.css"]["file"]
    stylesheet_link_tag("/#{vite_folder}/#{file}", media: "all")
  end

This file will contain all global and component CSS. This isn't optimal for large apps, but have to start somewhere.

Svelte 5 recently also introduced the css: 'inject' compiler option, but according to Rich Harris, this is only for toy projects that can't figure out how to use the manifest.

@pedroborges
Copy link
Collaborator

#1970 has been merged, and SSR should now work correctly with both Svelte 4 and 5. You can refer to the Svelte playgrounds as examples. Let me know if you run into any issues!

@buhrmi
Copy link
Contributor Author

buhrmi commented Sep 25, 2024

This shouldn't be closed as this is still a problem with Svelte 5. Or can you point me to where in the playground example you are rendering the component CSS during SSR?

@pedroborges
Copy link
Collaborator

@buhrmi If you're still experiencing this issue with Svelte 5, please feel free to reopen the PR. Additionally, providing a reproducible repository would help us investigate.

@buhrmi
Copy link
Contributor Author

buhrmi commented Sep 25, 2024

@pedroborges just add any CSS in a <style> tag to any Svelte component and you will see the style being applied AFTER the initial render.

I see that the Svelte 5 playground code has no component styles whatsoever, so I guess that's why you're not experiencing it.

Let me know if you still require a repo.

@buhrmi
Copy link
Contributor Author

buhrmi commented Sep 25, 2024

Also, the PR was only for Svelte 4. As I've stated here, we are still lacking a solution for this problem for Svelte 5.

@pedroborges pedroborges reopened this Sep 25, 2024
@buhrmi
Copy link
Contributor Author

buhrmi commented Sep 25, 2024

Looks like 3 months ago they added the css: 'inject' compiler option in Svelte 5, which adds back the CSS. According to Rich Harris, this is only for toy projects. It does work, however. I'll just make a PR to the playground that adds the compiler option, even if Rich will call us a toy project for all of eternity.

@buhrmi
Copy link
Contributor Author

buhrmi commented Sep 26, 2024

okay I can confirm that the css: 'inject' compiler option prevents layout flashing. closing.

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

Successfully merging a pull request may close this issue.

2 participants