Problem statement:
I have a scenario whereby I must decide during runtime which global css file to load/import into my app.
- Suppose following global css files which set-up BRAND specific variable values:
src/css/brand-a.css
src/css/brand-b.css
example of contents (/src/css/brand-a.css
):
:root {
@mixin theme-brand-a; // theme-brand-a is a mixin sourcing global variables for brand-a
}
Attention: Notice that the css must undergo preprocessing so pre-building under /public/css/<brand>.css
is not an option
Root app file: src/pages/_app.tsx
type OwnPageProps = {
brand: "a" | "b"
};
const MainApp = ({ Component, pageProps }: AppProps<OwnPageProps>) => {
const { brand } = pageProps;
// Need to import brand-specific css
return <Component {...pageProps} />
}
Attempt 1:
import from "src/css/brand-a.css"
import from "src/css/brand-b.css"
FAIL:
CSS Results in one huge style.css with global styles overwritting each other
Attempt 2 (trick the next/dynamic to load global as module):
src/components/CssLoaderBrandA.tsx
src/components/CssLoaderBrandA.module.css
src/components/CssLoaderBrandB.tsx
src/components/CssLoaderBrandB.module.css
src/components/CssLoader.tsx
Example of CssLoaderBrandA.ts
:
import React from 'react';
import './CssLoaderBrandA.module.css';
const CssLoaderBrandA = () => <p />;
export default CssLoaderBrandA;
Example of src/components/CssLoader.tsx
:
export const CssLoader = ({ brand }: CssLoaderProps) => {
switch (brand) {
case 'A':
dynamic(() => import('./CssLoaderBrandA'));
break;
case 'B':
default:
dynamic(() => import('./CssLoaderBrandB'));
break;
}
return <p />;
};
Example of src/pages/_app.tsx
const MainApp = ({ Component, pageProps }: AppProps<OwnPageProps>) => {
const { brand } = pageProps;
// Need to import brand-specific css
return <>
<CssLoader brand={brand} />
<Component {...pageProps} />
</>
}
FAIL: Syntax error: Selector “:root” is not pure (pure selectors must contain at least one local class or id)
Attempt 3:
Alter webpack to remove ALL css/sass/scss loaders and rules and define own chunks for css and load them as ‘asset/resource’
FAIL:
The css gets generated under .next/server/static/css/brand-a.css
and any imports give 404 for the generated file.
Question: How do I please Nextjs to allow me dynamically to import the css?