Windows 10
angular-cli: 1.0.0-beta.16
### Repro steps.
-
### The log given by the failure.
-
I am currently working on an angular2 project for production created in angular-cli (I know it might not be the best approach but it was not my decision) and the problem we are currently facing is using different stylesheets per customer. I have seen that webpack starter project allows you to do it in various ways, e.g. using htmlwebpackplugin to inject stylesheets on the runtime, however I could not figure it out how to do such thing for angular-cli project. So my actual question is whether there is a way for angular-cli to somehow switch those stylesheets dynamically by specifying a string argument such as brand to load correct file?
We don't have such functionality at runtime, no. But it's possible to inject CSS via javascript code, so I'd search the net for those techniques. I think https://material.angularjs.org/latest/ did that, for instance.
At build time you could I suppose, but then you'd have to make a build for each client.
Thank you for reply!
Apologies I realise this issue has been closed but it best matches my exact use-case and current problem.
I have an application used by multiple customers, each of which require their own unique theme/color scheme loaded at run time.
I'm currently using APP_INITIALIZER to grab the contents of a .json configuration file at the bootstrapping stage.
i.e.
export function createAppConfigFactory(config: AppConfigService) {
return () => config.load();
}
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: createAppConfigFactory,
deps: [AppConfigService],
multi: true
},
The config file specific to each customer appears as below:
{
"apiUrl": "http://localhost:64380/api",
"clubName": "development",
"colorScheme": "green"
}
I'm able to obtain the current configuration/colorScheme values at run-time within my components and have looked into a solution proposed in this discussion. This approach involves effectively overriding the @Component decorator. However, appending a value to the styleUrls property at construction (using the current customers config) would require me to have multiple style sheets for every component that references some colorScheme specific variable in it's styles sheet (I am using sass).
My questions are is there any _md-theme_ attribute equivalent in Material 2 and failing that does anyone have a clean method to deal with this issue ?
@bartlomiejkuczma did you happen to come up with a clean solution for this ?
Many Thanks
I managed to find a way around this by creating various themes for material 2 in my global styles sheet. I then used APP_INITIALIZER to fetch a config file and read in the color scheme desired by the relevant customer in the constructor of my main app component.
I then use a containing tag like the following with a variable used to select the class/theme for use by all child components:
Where {{theme}} is a member of my root component populated via the loaded config so theme = "green" or similar. If anyone stumbles across this thread and would like further explanation feel free to contact me.
Thanks
@JoshMarler can you please elaborate. I have a similar usecase.
@JoshMarler could you please provide an example or a sample project link.
@JoshMarler I am also looking for a clean way to achieve this. A sample would have been much appreciated.
@JoshMarler providing an example will be helpful for us to implement the functionality.
Hi guys. Sorry for missing this. The approach was something I actually implemented at my last job. I think I can still get access to that code though so I will dig it up over the weekend and post an example. Apologies for the wait!
@JoshMarler - looking very much forward to a detailed solution.
@filipesilva - any other approach? Theming application based on different clients is a very basic requirement as clients would want to apply some basic brand colors. Would not make sense to have different builds for each clients only for swapping the color themes. Needs to be through some dynamic parameter.
looking for dynamic theme , external to app
as I want to add new client as they signup- add scss/css files as required.
Any idea?
Appreciate your help
@JoshMarler Did you find anything?
Hey folks! For my project I use such approach
_app.component.html_
<link rel="stylesheet" href="/theme/css/vendor-rtl.min.css" *ngIf="(locale$ | async)?.isRtl else ltrVendor">
<link rel="stylesheet" href="/theme/css/common-rtl.min.css" *ngIf="(locale$ | async)?.isRtl else ltrCommon">
<link rel="stylesheet" href="/theme/css/application-rtl.min.css" *ngIf="(locale$ | async)?.isRtl else ltrApplication">
<ng-template #ltrVendor>
<link rel="stylesheet" href="/theme/css/vendor.min.css">
</ng-template>
<ng-template #ltrCommon>
<link rel="stylesheet" href="/theme/css/common.min.css">
</ng-template>
<ng-template #ltrApplication>
<link rel="stylesheet" href="/theme/css/application.min.css">
</ng-template>
<router-outlet></router-outlet>
Not very elegant solution, but works well. Maybe on "polishing" sprint I'll found better solution =)
In my project I have done something like accessing body element from app.component and setting appropriate theme css class. Then styling might be done thru usual SASS:
....
.my-theme1{
a{color:blue};
}
.....
my app.components.ts
....
constructor(private vcr: ViewContainerRef){
this.vcr.element.nativeElement.parentElement.classList.add('my-theme1');
}
.......
good discussions very helpful - I am also exploring ways if we can change complete HTML layout depending on each customer. Somehow dynamically change the page layout based on different customers . Mapping between {customer1: layout1, customer2:layout2 } can preexist but there has to be a way to apply it .
I put together an Angular project here with Bootstrap 4 and able to switch themes dynamically.
Here is a function I am using
where _theme_ is an object of mine that contains a _url_ variable to load css from
setTheme(theme) {
window.localStorage.setItem('theme', JSON.stringify(theme));
this.theme = theme;
let link = document.getElementById("css-theme");
if(link) {
link['href'] = this.theme.url;
} else {
let node = document.createElement('link');
node.href = this.theme.url; // insert url in between quotes
node.rel = 'stylesheet';
node.id = 'css-theme';
document.getElementsByTagName('head')[0].appendChild(node);
}
}
I'm using
window.localStorage.getItem(JSON.parse(theme));
in another function to set _theme_ upon load.
@JoshMarler - Any findings??
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
I put together an Angular project here with Bootstrap 4 and able to switch themes dynamically.