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.
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:
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:
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.
In app.html
, above %sveltekit.head%
, add another template variable.
%sveltekit.globalcss%
%sveltekit.head%
It will be replaced by the stylesheet element.
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>
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
!
{
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.
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.