vite-plugin-svelte-globalcss

Vite Plugin Svelte Globalcss

Use global css/sass in a sveltekit app.

Heads up: Deprecation notice

Importing the css/sass directly in a Svelte component will work almost just as well, except for a slowdown when hot reloading. Use this project as a way to understand the internals of Rollup, Vite and Sveltekit instead of actually using it.

vite-plugin-svelte-globalcss

A Sveltekit plugin that enables you to include a global css/sass file in your Sveltekit project. Supports hot reloading.

When using a css framework like Bulma, you configure layout, spacing, typography, etc, by variables that will be used throughout the project as css classes, for example is-size-3 has-background-primary-light. This is largely incompatible with Svelte's component css which is isolated from the rest of the project.

Furthermore there seems to be no way to include a global css file without jumping through a lot of hoops. The simple solution would be just to add a <link rel="stylesheet" href="..." /> element in app.html. But that has a few drawbacks:

  • You can't just link to a stylesheet without asking for cache problems, so you must regularly bust the cache
  • If your file is built with Sass, you must compile it in a separate build step
  • The file you linked to won't be hot reloaded in Sveltekit.

Configuration

Unfortunately there are still a few hoops you need to jump through to make it work, but you will be rewarded with a seamless experience; on the dev server you can save your Sass file and it will be hot reloaded, when building for production the css file will be built as a file included in the normal output, referenced with a cache busting filename from Vite.

There are four things you need to do:

1. Adding the plugin

Import and add the plugin to vite.config.js with the fileName attribute pointing to your css/sass file:

import { sveltekit } from '@sveltejs/kit/vite';
import { globalcss } from 'vite-plugin-svelte-globalcss'

/** @type {import('vite').UserConfig} */
const config = {
    plugins: [sveltekit(), globalcss({ fileName: './src/sass/app.scss' })]
}

export default config

This will build and compile your file automatically.

2. Modifying app.html

In app.html, above %sveltekit.head%, add another template variable.

%sveltekit.globalcss%
%sveltekit.head%

It will be replaced by the stylesheet element.

3. Modify the main Svelte component

This code is for the hot reloading functionality. In the main Svelte component or __layout.svelte, add this code:

<script>
  import { globalcss } from 'vite-plugin-svelte-globalcss/client'
  globalcss()
</script>

4. Adding a hook

The final part is to rewrite the html response to actually replace the %sveltekit.globalcss% variable. If you're not using SvelteKit hooks, this is very simple to add. Create a src/hooks.js file with the following content:

export { handle } from 'vite-plugin-svelte-globalcss/hooks'

If you're already using a hooks file, you can import the transformGlobalcss function and use it as an option to handle:

import { transformGlobalcss } from 'vite-plugin-svelte-globalcss/hooks'

/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
  const response = await resolve(event, {
    transformPageChunk: transformGlobalcss()
  });
 
  return response;
}

After all this, you can finally enjoy your enhanced Sveltekit project with npm run dev and npm run build!

Plugin options

{
    fileName : string

    // See note below if you really need to change this.
    outputFilename? = "global.css"

    // See https://sass-lang.com/documentation/js-api/interfaces/Options
    sassOptions? = sass.Options<"sync">

    // Sveltekit assets directory, outputFilename will be placed here in dev mode.
    assets? = "static"
}

Note: If you change outputFilename, you must also pass that value to the transformGlobalcss({cssFile: outputFilename}) function in your hooks file.

Issues

Creating a plugin like this by understanding the Rollup build process, configuring typescript, figuring out how Rollup/Vite/Svelte interacts, publishing the plugin to NPM with the correct module settings, etc, is honestly quite a lot of work and generally frustrating, so I'm sure this plugin has a lot of issues. Let me know if you find something, or even better, help me out with a PR or good advice. Things aren't supposed to be this complicated.

Top categories

Loading Svelte Themes