Skip to content

Initial render does not include stitches SSR styles #8392

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

Closed
lhjt opened this issue Jan 8, 2023 · 3 comments
Closed

Initial render does not include stitches SSR styles #8392

lhjt opened this issue Jan 8, 2023 · 3 comments

Comments

@lhjt
Copy link

lhjt commented Jan 8, 2023

Describe the bug

I am unsure if I should be filing this here in stitches, but I have yet to encounter this issue with remix or nextjs SSR, so I am filing it here.

Context

Stitches is a CSS-in-JS solution that requires that users of the library call a method called getCssText() and inject it into the head of their project for SSR, such that all styles are present on the first render.

The Problem

I am currently injecting the styles into the svelte:head component like so (the funny additions are due to an open bug):

<svelte:head>
    {@html `<${''}style>${getCssText()}</${''}style>`}
</svelte:head>

However, the problem is that for some reason, svelte kit does ?? (I am assuming) on the first render such that the styles I have written are not present on the first SSR run of the page (check reproduction).

First render:

<!-- HEAD_svelte-3qrx6s_START --><!-- HTML_TAG_START --><style>
  --sxs {
    --sxs: 1 iptfga;
  }
  @media {
    body {
      background: red;
    }
  }</style
><!-- HTML_TAG_END --><!-- HEAD_svelte-3qrx6s_END -->

All renders afterwards (note the class declaration visible that sets the color to green):

<!-- HEAD_svelte-3qrx6s_START --><!-- HTML_TAG_START --><style>
  --sxs {
    --sxs: 1 iptfga;
  }
  @media {
    body {
      background: red;
    }
  }
  --sxs {
    --sxs: 2 c-iUYyiF;
  }
  @media {
    .c-iUYyiF {
      color: green;
    }
  }</style
><!-- HTML_TAG_END --><!-- HEAD_svelte-3qrx6s_END -->

This issue also extends to prerendering. If I set prerender to true and export that in the root layout, the missing stitches styles are never injected.

Reproduction

  1. Clone the repository. (This is just a basic svelte kit skeleton that was generated)
  2. Install the dependencies and start the development server.
  3. Make a request to / with curl or xh or your HTTP utility of choice, and observe that the style tag that is injected does not have the color: green declaration.

image

4. Make another request after the previous one and observe that the style tag now includes the missing `color: green` declaration, as does every subsequent request after the initial render.

image

Logs

No response

System Info

System:
    OS: macOS 13.2
    CPU: (10) arm64 Apple M1 Max
    Memory: 2.16 GB / 64.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.9.1 - ~/.nvm/versions/node/v18.9.1/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.9.1/bin/yarn
    npm: 8.19.1 - ~/.nvm/versions/node/v18.9.1/bin/npm
  Browsers:
    Chrome Canary: 111.0.5525.1
    Firefox Developer Edition: 106.0
    Safari: 16.2
  npmPackages:
    @sveltejs/adapter-auto: 1.0.0 => 1.0.0
    @sveltejs/adapter-node: 1.1.0 => 1.1.0
    @sveltejs/kit: 1.0.7 => 1.0.7
    svelte: 3.55.0 => 3.55.0
    vite: 4.0.4 => 4.0.4


### Severity

annoyance

### Additional Information

_No response_
@Rich-Harris
Copy link
Member

Candidly, I would avoid this technique. It involves runtime overhead, and because it uses <style> instead of <link> for delivering styles it means your CSS cannot be cached. This will result in worse performance for your app.

You can get it to work, by moving the <svelte:head> below the <slot /> (meaning that the css(...) call happens before getCssText() runs), but there's a subtle bug — add a new route...

<!-- src/routes/other/+page.svelte -->
<script>
  import { css } from '@stc';

  const blah = css({
    color: 'yellow'
  });
</script>

<h1 class={blah()}>Other page</h1>

...and notice that when you run the app, if you visit /other and then visit /, the styles for /other will be included on the / page... and every page that gets visited after that. Essentially, every page will include every style for every page that has ever been visited by anyone, because (AFAICT) every new css(...) call adds stuff to an ever-growing ball of styles that are assumed to apply universally.

I'm sure there's a way to change that behaviour — a reset function or something — but the fact that this footgun exists in the first place is a bit alarming.

I don't know why the @stitches/react one works for Next et al while @stitches/core has this behaviour — probably something to do with double rendering. But I'm going to close this issue since SvelteKit is behaving as expected.

@Rich-Harris Rich-Harris closed this as not planned Won't fix, can't repro, duplicate, stale Jan 8, 2023
@lhjt
Copy link
Author

lhjt commented Jan 8, 2023

Thanks for looking at this and suggesting this workaround - it does lead to the result that I was looking for.

In regards to the essential "snowballing" of these styles and the inability to have the CSS cached due to the use of the style tag - interesting insights; I am evaluating svelte for the first time and just trying to work things out, so given this information I may end up re-evaluating my preference to use stitches and determine if there is another solution that would yield better results for svelte (or if the stitches team have any extra information on this).

@felixakiragreen
Copy link

I upgraded to SvelteKit 2 and now I'm facing the same issue.

I wasn't able to get your workaround working @Rich-Harris , but I did find another work around, since you suggested using <link> is better than <style>.

I copy-pasted the output of getCssText() into a css file, that I'm importing just for production. It's hella hacky, but I really don't want to downgrade to SvelteKit 1 or stop using Stitches.

The one issue I found was that using background images doesn't work because the suffixes like .92M7RN3h.svg don't get added to it. So I just stopped using background urls in my stitches css. 😂

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

3 participants