Self-hosted fonts in Slidev
Slidev is a fantastic tool for code-focused presentations. Slides are written in Markdown, giving us all the nice features from code documentation like syntax highlighting.
Slidev is built with Vue and Vite and provides a Single Page Application (SPA) export for static hosting. This is a nice way to “hand out” interactive slides to presentation attendees afterwards.
One drawback is the use of Google Fonts by default. There are major privacy concerns and using Google Fonts without prior consent violates GDPR.
Thankfully, Slidev allows lots of customizations without the need to develop a completely new theme.
Disable Google Fonts
In the base slides.md
file, disable the Google Fonts provider in the YAML frontmatter:
---
fonts:
provider: none
---
Disabling the fonts provider leaves us with system fallback fonts. We can stop here, but the presentation experience may become inconsistent depending on the device it’s viewed on.
Install custom fonts
It is possible to download the necessary custom fonts from Google Fonts and drop them into your presentation folder. Though, Fontsource is a much nicer way to include open-source fonts in projects already using npm.
The default Slidev theme needs the fonts Nunito Sans and Fira Code:
npm install @fontsource/nunito-sans @fontsource/fira-code
Include font files
As of yet, Slidev doesn’t know about the custom font files. We can add the @font-face
declarations to the style.css
file, which is automatically picked up by Slidev.
Fira Code has the benefit of being a variable font, so we need only one @font-face
declaration to get all weights. For Nunito Sans we need to manually import different weights and styles.
For the default theme, the following declarations are necessary:
/* Nunito Sans */
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 300;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-300-normal.woff2")
format("woff2");
}
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 300;
font-style: italic;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-300-italic.woff2")
format("woff2");
}
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 400;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-400-normal.woff2")
format("woff2");
}
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 400;
font-style: italic;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-400-italic.woff2")
format("woff2");
}
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 600;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-600-normal.woff2")
format("woff2");
}
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 600;
font-style: italic;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-600-italic.woff2")
format("woff2");
}
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 700;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-700-normal.woff2")
format("woff2");
}
@font-face {
font-family: "Nunito Sans";
font-display: swap;
font-weight: 700;
font-style: italic;
src: url("@fontsource/nunito-sans/files/nunito-sans-latin-700-italic.woff2")
format("woff2");
}
/* Fira Code */
@font-face {
font-family: "Fira Code";
font-display: swap;
src: url("@fontsource/fira-code/files/fira-code-latin-variable-wghtOnly-normal.woff2")
format("woff2");
}