Next.js Discord

Discord Forum

Using Next w. vanilla-extract & global themes

Unanswered
Cornish Rex posted this in #help-forum
Open in Discord
Cornish RexOP
I have an existing design-system built with vanilla-extract that I want to use with Next (preferably, using the app router).

The design system consists of two parts:
* X amount of components, all styled with vanilla extract, and utilising vars for theming bits (color, spacing etc).
* X amount of themes, created using createGlobalThemeContract/ CreateGlobalTheme that defines the values for each variable per theme.

I’m using @vanilla-extract/next-plugin and importing the component themselves work just fine. My issue lies with resolving the correct theme.
When I import the theme using an regular import (import '@company/package/dist/esm/themes/theme/theme.css';) in layout.tsx it works just fine – the colors are resolved correctly, and the resulting css consists of one set of css :root variables.

Ideally though, I’d like to decide the theme via config (examplified below as a simple variable, but theoretically if could come from other places), and as soon as I switch the import from a regular to a dynamic one:

// When I change from this
import '@company/package/dist/esm/themes/theme/theme.css';

// To this
const theme = 'someTheme';
import(`@company/package/dist/esm/themes/${theme}/theme.css`)


…it stops to work. The underlying bundler goes over the dist/esm/themes/ folder, and resolves each and every theme.css file that it finds, and the result is a css file with x amount of sets of css :root variables, resulting in the ”wrong” theme being applied (last theme in the resulting document).

I guess the bundler does what it’s supposed to, it’s just that I wish for something else to happen for this particular case:
* Generate all of the theme css files at build time, so there’s one for each theme
* Either bundle one of them it together with the ”main” css file based on the active theme.
* …or keep it as a separate request, but only create a link rel="stylesheet" for the ”current theme”.

Any ideas? Am I approaching this wrong?

2 Replies

Cornish RexOP
Again, looking at the [webpack module documentation](https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import), it’s pretty obvious that the above behaviour is expected:

For example, import(./locale/${language}.json) will cause every .json file in the ./locale directory to be bundled into the new chunk. At run time, when the variable language has been computed, any file like english.json or german.json will be available for consumption.

Reading further, I wonder if I could make this work using [magic comments](https://webpack.js.org/api/module-methods/#magic-comments) (some variant of webpackIncludeor webpackExclude) but I’ve had no luck getting anything to stick/work just yet.
Cornish RexOP
…aand obviously using a webpack-centric solution is not ideal at all. But I'm not sure what my alternatives are at this point?