When deciding how to develop multiple themes/brands, there are several gradations of customizability.
Deciding on how to approach this is a trade-off between the amount of customizability and the amount of code duplication.
This requires discipline from the developer that we maintain the 'Single responsibility' principle for components. Components that actually serve two completely separate functionalities depending on the brand are not desirable.
Create a Config.graphqls in your graphql directory with the following contents:
enum ThemeName {
BRAND_1
BRAND_2
}
extend input GraphCommerceStorefrontConfig {
themeName: ThemeName!
}
Applying a different theme based on the store configuration:
// in _app.tsx
const { themeName } = useStorefrontConfig()
const theme = useMemo(() => {
if (themeName === 'BRAND_1') {
const brand1Palette = ...
return createThemeWithPalette(brand1Palette)
}
}, [domain])
Applying a different component based on the store configuration:
export function MyComponent() {
const { themeName } = useStorefrontConfig()
if (themeName === 'BRAND_1') return <Brand1Component>
return <Brand2Component {...}/>
}
Create a Config.graphqls in your graphql directory with the following contents:
enum ThemeName {
BRAND_1
BRAND_2
}
extend input GraphCommerceConfig {
themeName: ThemeName!
}
During deploy you'd have to set the theme that is being build:
GC_THEME_NAME=BRAND_1
.
Create a separate theme for each brand:
let theme: Theme
if (import.meta.graphCommerce.theme === 'BRAND_1') {
const brand1Palette = ...
theme = createThemeWithPalette(brand1Palette)
} else if (import.meta.graphCommerce.theme === 'BRAND_2') {
const brand2Palette = ...
theme = createThemeWithPalette(brand2Palette)
}
theme.components = createOverrides(theme) as Components
export { theme }
Replace/Plugin a component based on the theme:
// plugins/BRAND_1/magento-product/Replace.tsx
export const config: PluginConfig<'themeName'> = {
type: 'replace',
module: '@graphcommerce/magento-product',
ifConfig: ['themeName', 'BRAND_1'],
}
export function ProductListItem(props: ProductListItemProps) {
//...
}
Now when a new brand is added you can copy-paste the BRAND_1 directory and you should be able to modify the components to your liking.