Svelte / Sapper with Sass!

Sean Schertell
Sep 4 · 3 min read

The Svelte-based web framework Sapper gives us a lot out of the box. Declarative routing, free SSR for every route, baked in support for API routes, and so much more. But if you want to use Sass or Stylus or another preprocessor, you’re on your own. 😕

There are 3 things we want to do…

  • Parse Sass within <style lang="scss"> tags.
  • Apply a global theme to the entire site and make variables/mixins available everywhere.
  • Get VS Code syntax highlighting support for Sass in .svelte files.

1. Parse <style lang="scss"> tags

First, we need to add a couple NPM modules:

npm i -D svelte-preprocess autoprefixer node-sass

Now modify rollup.config.js to apply the preprocessing:

Import sveltePreprocess

import sveltePreprocess from 'svelte-preprocess';

Setup the preprocessing function

Set it up once near the top of the file so that it can be referenced from both client and server blocks.

const preprocess = sveltePreprocess({
scss: {
includePaths: ['src'],
},
postcss: {
plugins: [require('autoprefixer')],
},
});

Call preprocess from both the client and server blocks

Adding one line inside both blocks:

export default {
client: {
plugins: [
svelte({
// ...
preprocess, // <-- ADD THIS LINE
}),
},
server: {
plugins: [
svelte({
// ...
preprocess, // <-- HERE TOO
}),
],
},
};

So now, if you add lang=scssto your style tags within a svelte component, it should happily parse as Sass.

Remember to add lang=”scss” to style tags!

2. Make a global theme and variables/mixins

I like to create a src/styles/ directory with global.scss and theme.scss. The theme.scss will contain variables and mixins which can be imported and used site-wide. The global.scss will also import theme.scss and will use some of those settings to set up the basic layout for the site.

💡 Svelte doesn’t have a good way of creating a truly global scss file that gets used everywhere by default. So don’t bother with setting up a postcss plugin for rollup to try to generate css bundles for you. It’s possible but doesn’t work very well because your variables and mixins won’t be available to your components at all — which kinda ruins one of the big advantages of using Sass in the first place.

Add this to your src/ directory:

style/
global.scss
theme.scss

global.scss

// global.scss
@import "./theme.scss";
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
}
...

theme.scss

// theme.scss
$main-color: blue;
$site-width: 1200px;
...

Now to apply those, we’ll import global into _layout.svelte like this:

// _layout.svelte
<style lang="scss" global>
@import "./style/global.scss";
</style>

💡 Notice that we added the lang attribute for Sass parsing and also the globalkeyword so these styles will be applied globally.

To use variable/mixins, we can import theme.scss into any Svelte component like this:

// my-component.svelte
<style lang="scss">
@import "./style/theme.scss";
h1 {
color: $main-color;
}
</style>

3. Fix VS Code syntax

To get VS Code to stop highlighting all the “errors” in your style tags, we need to use the VS Code Svelte extension and tell it to parse SCSS within those tags. So first, install the “Svelte” extension from within VS Code.

Next, create a svelte.config.js at top level of project with:

const sveltePreprocess = require('svelte-preprocess');module.exports = {
preprocess: sveltePreprocess({
scss: {
includePaths: ['src'],
},
postcss: {
plugins: [require('autoprefixer')],
},
}),
};

You may also need to tell the Svelte extension the path to Node. If so, just open VS Code > Preferences > Settings and search for “svelte”. Right at the top, you should see: “Svelte > Language-server: Runtime”. You need to supply your Node path there. To get it, pop open a terminal and type which node, then copy/paste that path there. Mine is: /usr/local/bin/node but yours might be different.

If it still highlights valid SCSS as invalid even after closing and reopening the file, you might try making sure that VS Code also has the “SCSS Style Tag” extension installed.

Conclusion

Yes, it feels like all this work shouldn’t be necessary for something as basic as CSS preprocessing. But the good news is that you probably only need to do it once because you can save this stuff and use it as your boilerplate for the next project. For everything Svelte and Sapper give to us developers, it’s worth it. But it sure would be nice if it were a little easier. ;-)

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade