I'm developing a NuxtJS website and the pages/components can have either a generic design by default, either one that is customizable by client, and will be specified in the url.
Something alone the lines of:
http://localhost:3000/registration - For a generic page
http://localhost:3000/client-name/registration - Client specific page
To achieve that goal, I have a JSON configuration file per client (say client-name.json) that has this structure.
{
"some_configuration_property": {},
"another_configuration_property": {},
"design": {
"logoUrl": "/assets/client-name/logo.png",
"backgroundColor": "#000000",
"primaryColor": "#ffffff",
"secondaryColor": "#ffff00"
},
}
To start things, I implemented the routing system and I can successfully read each client's configuration based on the current route (inside the <script> tag of the Vue file of that route), inside the setup method (I use @nuxt/composition-api).
The problem that I'm facing now is to figure out how to pass these "design variables" into the <style> tag of my Vue file, which uses SCSS. The behaviour that I wanted to implement was to have a default design for a specific component/page, but that could be overridden by these "design variables" specific to each client.
- The first thing that came to my mind was to use CSS variables, that would allow me to create variables with a default values but that I would be able to override inside the styles. I created a sample component for test and it worked with CSS properties and the v-deep pseudo element. However, this means that I would have to create a class for each client in the customized component and that's what I'd like to avoid. I first thought to this approach because it would give me a lot of flexibility about how I choose to use these design colors inside the styles.
Example:
// From the customizable component
.my-button {
color: (--button-color, teal);
}
// Styling from a parent component/view
// Had to create a selector with a style like <div> for superior specificity though, not so clean
v::deep {
div {
&.my-button {
--button-color: purple;
}
}
}
I've seen the
/deep/selector or::v-deeppseudo selector but I don't think it's a very clean solution since it would be used a lot in the codebase. Styling component from parents would make the code hardly maintainable.Another approach could be to pass a variable,
classArrayfor instance, inside the setup method to dynamically bind CSS classes on the DOM elements. Although, it would be way too cumbersome to create a CSS class per client with the associated styles.
Like this:
<template>
<my-button :class="classArray"></my-button>
</template>
<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
name: 'MyPage',
setup() {
const clientName = 'someClientName';
const classArray = [clientName]
return { classArray };
},
})
</script>
<style lang="scss" scoped>
.someClientName {
// some custom styles
}
</style>
What would be your approach in this situation?
Thanks for help!