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

Load css files on +layout.svelte conditionally based on server-side data #9943

Open
martgnz opened this issue May 16, 2023 · 8 comments
Open

Comments

@martgnz
Copy link

martgnz commented May 16, 2023

Describe the problem

We are trying to import a.css on a layout file, and when a prop coming from +layout.server.js is met, load b.css.

CSS files imported from components load regardless of the svelte component getting rendered on the markup. This is a problem because we haven't found another way to load global css files based on SSR props.

Describe the proposed solution

Ideally we could simply do the following:

<script>
  // +layout.svelte
  import './styles/a.css';
  import Theme  from './Theme.svelte';

  export let data;
</script>

<!-- b.css is not loaded when condition is false  -->
{#if data.condition}
  <Theme />
{/if}

<slot />
<script>
  // Theme.svelte
  import './styles/b.css';
</script>
<script>
  // +layout.server.js
  export async function load(event) {
    return { condition: false }
  }
</script>

Alternatives considered

We have taken a look at the layout system. Unfortunately it seems to designed around routes and not really around props coming from a server.

Importance

would make my life easier

Additional Information

We are not sure how to proceed maintaining SSR. Would appreciate any suggestions or ideas!

@DhyeyMoliya
Copy link

DhyeyMoliya commented May 17, 2023

You can use <svelte:head> to include your stylesheets conditionally using <link rel="stylesheet" .../>.

Example :

<script>
    export let data;
</script>

<svelte:head>
    {#if data.condition}
	<link rel="stylesheet" href="/styles/a.css" />
    {:else}
        <link rel="stylesheet" href="/styles/b.css" />
    {/if}
</svelte:head>

Note : You need to have these files publicly accessible in /static directory of the project, i.e. /static/styles/a.css or something like that.

OR

You can use Advanced Layouts to achieve similar results.
See here : https://kit.svelte.dev/docs/advanced-routing#advanced-layouts

@martgnz
Copy link
Author

martgnz commented May 17, 2023

Thanks Dhyey. In this case we would prefer to avoid loading stylesheets from the static folder. Right now we have every style in the same folder and it's very easy to keep track of them. Moving only some of them elsewhere is something we want to avoid.

I was taking a look at the advanced layouts but in this case we are only working with one index.svelte page that loads props from a server and ideally loads different css based on that. The theming doesn't depend on a path, it depends on a prop loaded from a server and as far as I know this behaviour is always based on pages being under different routes.

As for the last example the problem is that importing CSS on a component and then loading that on a layout file automatically applies all the styles, even when that component is not being rendered on the markup. You don't have a way to control when they're loaded.

@DhyeyMoliya
Copy link

Yes that's the hard truth which I am facing since the inception of SvelteKit. Conditional Styling is a pain to implement with SvelteKit.

@benmccann
Copy link
Member

I'd guess this is related to vitejs/vite#4389

Can you change it to do a dynamic import of the component inside the if check? That will probably work instead

@martgnz
Copy link
Author

martgnz commented May 19, 2023

@benmccann A dynamic import inside an await block works but the problem is that you lose SSR. Is there a way to have this keeping SSR?

@benmccann
Copy link
Member

I don't think you would lose SSR with that

@martgnz
Copy link
Author

martgnz commented May 19, 2023

Unfortunately I am losing SSR in the following example (CSS appears to load client-side): https://stackblitz.com/edit/sveltejs-kit-template-default-eun2mo?file=src%2Froutes%2F%2Bpage.svelte

@david-plugge
Copy link
Contributor

You can try to load the theme component in layout.js and pass it to layout.svelte

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

4 participants