Using React Router
Easily use Bamboo with React Router with our dedicated integration.
Start a new project
Create project
To get started, we will need to create a new React Router project using the official Create React Router (opens in a new tab) CLI. In this guide, we will use TypeScript.
If you don't enter any parameter, the CLI will guide you through the process of creating a new React Router app.
You will be asked a few questions, answer these as follows:
? Where should we create your new project? test-app
? Install dependencies? NoNote: You should decline the dependency installation step as we will install dependencies together with Bamboo CSS.
Install Bamboo
Install bamboo and create your bamboo.config.ts file. React Router builds with Vite, so this is the Vite integration —
@bamboocss/vite is the compiler, and it is what keeps the style engine out of your client bundle.
Update package.json scripts
Add "prepare": "bamboo codegen" to scripts. It runs codegen after every dependency
install, so the output directory can stay in .gitignore.
The build itself no longer needs it. The Vite plugin generates styled-system/ in buildStart, before anything
resolves an import of it, so a fresh clone builds without a separate codegen step. Keep the script regardless: tsc and
your editor read the generated types without ever running the plugin.
Configure the content
Make sure that all of the paths of your React Router components are included in the include section of the
bamboo.config.ts file.
This matters more under the compiler than it used to: a module it compiles that the extractor never read would have
class names with no rules behind them, so the build fails instead. ./app/**/* covers app/root.tsx as well as
everything under it.
bamboo.config.ts
import { defineConfig } from '@bamboocss/dev'
export default defineConfig({
// Whether to use css reset
preflight: true,
// Where to look for your css declarations
include: ['./app/**/*.{js,jsx,ts,tsx}'],
// Files to exclude
exclude: [],
// The output directory for your css system
outdir: 'styled-system',
})Replace Tailwind CSS with Bamboo CSS
Remove the Tailwind CSS plugin from vite.config.ts and add Bamboo's. The template's app/app.css, its import in
app/root.tsx, and any links entry pointing at it can go too — the next step imports Bamboo's stylesheet instead.
vite.config.ts
import { reactRouter } from '@react-router/dev/vite'
import bamboocss from '@bamboocss/vite'
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [bamboocss(), reactRouter(), tsconfigPaths()],
})There is no postcss.config.cjs entry for Bamboo and no file carrying the @layer statement: the plugin serves the
stylesheet as a virtual module that emits its own layer order. You still need PostCSS for anything else you run through
it, autoprefixer included.
Import the virtual stylesheet
Import it once, from app/root.tsx:
app/root.tsx
import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router'
import type { Route } from './+types/root'
import 'virtual:bamboo.css'
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
)
}It has to be a JavaScript import. @import from a stylesheet does not reach it, because Vite resolves CSS @import
before plugin resolution and the id names a virtual module this plugin resolves.
Create app/vite-env.d.ts, or add the second line to it if your template already has one, so TypeScript accepts that
import:
app/vite-env.d.ts
/// <reference types="vite/client" />
/// <reference types="@bamboocss/vite/client" />Start your build process
Start the dev server with pnpm dev.
Start using Bamboo
app/routes/home.tsx
import type { Route } from './+types/home'
import { css } from '../../styled-system/css'
export function meta({}: Route.MetaArgs) {
return [{ title: 'New React Router App' }, { name: 'description', content: 'Welcome to React Router!' }]
}
export default function Home() {
return (
<div>
<h1 className={css({ fontSize: '2xl', fontWeight: 'bold' })}>Welcome to the home page</h1>
</div>
)
}Troubleshooting
If your IDE does not autocomplete styled-system imports, add that directory to include in tsconfig.json, alongside
app. See the CLI guide.