Custom Font
How to use custom fonts in your project.
Adding custom fonts to your application or website is a typical requirement for projects. Bamboo recommends using custom fonts through CSS variables for consistency.
Setup
Vite setup
Use the Vite integration, then load font packages or your own @font-face declarations from
the app's entry module. For example:
src/main.tsx
import 'virtual:bamboo.css'
import './fonts.css'Put self-hosted font files in public/fonts/ and reference them as /fonts/... in the CSS below. The same imports can
live in the root module or layout of a supported Vite framework.
Fontsource
Fontsource (opens in a new tab) streamlines the process of integrating fonts into your web application.
To begin, install your desired font package:
pnpm add @fontsource-variable/fira-code
Next, import the font into your project:
import '@fontsource-variable/fira-code'
Lastly, create a variable to use it as a token in the bamboo config
src/fonts.css
:root {
--font-fira-code: 'Fira Code Variable', monospace;
}Vanilla CSS
Declare self-hosted fonts in the stylesheet imported above:
@font-face {
font-family: 'Mona Sans';
src: url('/fonts/Mona-Sans.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
Then alias the font names to css variables.
:root {
--font-mona-sans: 'Mona Sans', sans-serif;
}
Declared this way the family name means nothing to Bamboo, which is why the steps below alias it to a variable and then
to a fonts token — the token is what fontFamily ends up accepting. Global Font Face skips that
by registering the name for you.
Global Font Face
You can also define global font face in your bamboo config. A family takes one face or an array of them, and each face's
src takes one source or an array of them.
This is the option to reach for rather than writing @font-face into global.css.
Both emit the same rule, but a family declared here is also registered as a value fontFamily accepts — so
css({ fontFamily: 'Fira' }) autocompletes and typechecks without a token. Written as a raw @font-face in
global.css, the name is a string Bamboo has never seen, and under
strictPropertyValues it is a type error.
export default defineConfig({
global: {
fontface: {
Fira: [
{
src: ['url(/fonts/fira.woff2) format("woff2")', 'url(/fonts/fira.woff) format("woff")'],
fontWeight: 400,
fontStyle: 'normal',
fontDisplay: 'swap',
},
{
src: 'url(/fonts/fira-bold.woff2) format("woff2")',
fontWeight: 700,
fontStyle: 'normal',
fontDisplay: 'swap',
},
],
},
},
})
Then expose the font names to css variables.
:root {
--font-fira-code: 'Fira Code Variable', monospace;
}
You can also use global.vars in your bamboo config to define the variables.
export default defineConfig({
global: {
vars: {
'--font-fira-code': 'Fira Code Variable, monospace',
},
},
})
Update Bamboo Config
export default defineConfig({
theme: {
extend: {
tokens: {
fonts: {
fira: { value: 'var(--font-fira-code), Menlo, monospace' },
mona: { value: 'var(--font-mona-sans), sans-serif' },
},
},
},
},
})
Use the custom fonts
import { css } from '../styled-system/css'
function Page() {
return (
<div>
<h1 className={css({ fontFamily: 'mona' })}>Mona Sans</h1>
<code className={css({ fontFamily: 'fira' })}>Fira Code</code>
</div>
)
}