<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ferdie Sletering</title>
    <description>The latest articles on DEV Community by Ferdie Sletering (@ferdiesletering).</description>
    <link>https://dev.to/ferdiesletering</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F524864%2Fcea58812-b2f2-48f0-8fe7-587d57158045.jpeg</url>
      <title>DEV Community: Ferdie Sletering</title>
      <link>https://dev.to/ferdiesletering</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ferdiesletering"/>
    <language>en</language>
    <item>
      <title>Angular Signals EventBus pattern</title>
      <dc:creator>Ferdie Sletering</dc:creator>
      <pubDate>Tue, 25 Jun 2024 10:09:49 +0000</pubDate>
      <link>https://dev.to/ferdiesletering/angular-signals-eventbus-pattern-15ce</link>
      <guid>https://dev.to/ferdiesletering/angular-signals-eventbus-pattern-15ce</guid>
      <description>&lt;p&gt;In several use cases, I find the event bus pattern to be very effective. Angular signals provide an excellent mechanism for managing state, so I decided to implement the event bus pattern using Angular signals.&lt;/p&gt;

&lt;p&gt;In my recent project, I am developing a dashboard where the widgets need to communicate with each other while remaining standalone. Each widget has its own state and API, making the event bus pattern a perfect fit for this scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  EventBus
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyie37abnkhxcsyo5nj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyie37abnkhxcsyo5nj2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Publish banana to the EventBus &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { SignalBusService } from 'ng-signal-bus' 

@Component({
  selector: 'app-widget-add-grocery-items',
  standalone: true,
})
export class WidgetAddGroceryItemsComponent {
  signalBus = inject(SignalBusService)

  constructor() {
    this.publish('fruit:banana', 'Banana')
  }

  publish(key:string, data: any) {
    this.signalBus.publish(key, data)
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Subscribe to the eventBus and listen for all fruits with the &lt;code&gt;fruit:*&lt;/code&gt; selector.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { SignalBusService } from 'ng-signal-bus' 

@Component({
  selector: 'app-widget-fruit-list',
  standalone: true,
})
export class WidgetFruitListComponent {
  signalBus = inject(SignalBusService)

  ngOnInit() {
     this.signalBus.subscribe('fruit:*', (metaData) =&amp;gt; {
      // Outputs { data: 'Banana', timestamp: 1434342 }
      console.log(metaData);
    });
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  metaData
&lt;/h3&gt;

&lt;p&gt;Inside the subscribe callback the service returns a metaData object&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

export interface MetaData {
  data: any;
  timestamp: number;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In this example, we use a simple string as the payload, but you can also provide an object.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

 this.publish('fruit:banana', { name: 'Banana', amount: 4 } )
// output
{
 data: { name: 'Banana', amount: 4 }
 timestamp: 232322 
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Full demo see &lt;a href="https://stackblitz.com/edit/stackblitz-starters-ahglvf?file=src%2Fapp%2Fwidget-add-grocery-items%2Fwidget-add-grocery-items.component.html" rel="noopener noreferrer"&gt;Stackblitz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/stackblitz-starters-ahglvf?embed=1&amp;amp;file=src%2Fmain.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;h2&gt;
  
  
  Package
&lt;/h2&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.npmjs.com/package/ng-signal-bus" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-production.npmjs.com%2F338e4905a2684ca96e08c7780fc68412.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.npmjs.com/package/ng-signal-bus" rel="noopener noreferrer" class="c-link"&gt;
          ng-signal-bus - npm
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Angular signal based message/event bus service for Angular.
 Under the hood it's using a signal to store and mutate data, the effect() calls the callback function to update subscribers.. Latest version: 0.2.2, last published: 2 months ago. Start using ng-signal-bus in your project by running `npm i ng-signal-bus`. There are no other projects in the npm registry using ng-signal-bus.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic-production.npmjs.com%2Fb0f1a8318363185cc2ea6a40ac23eeb2.png"&gt;
        npmjs.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;I have packaged the SignalBusService into an &lt;a href="https://www.npmjs.com/package/ng-signal-bus" rel="noopener noreferrer"&gt;NPM package&lt;/a&gt;, so you can easily use it in your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular Signal
&lt;/h3&gt;

&lt;p&gt;Under the hood it's using a signal to store and mutate data, the effect() calls the callback function to update subscribers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbx25ff26z5lu288qk8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbx25ff26z5lu288qk8s.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Only tested with Angular v18.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Angular Material Tabs with components inside the tabs</title>
      <dc:creator>Ferdie Sletering</dc:creator>
      <pubDate>Wed, 19 Jun 2024 14:01:07 +0000</pubDate>
      <link>https://dev.to/ferdiesletering/angular-material-tabs-with-components-inside-the-tabs-56ki</link>
      <guid>https://dev.to/ferdiesletering/angular-material-tabs-with-components-inside-the-tabs-56ki</guid>
      <description>&lt;p&gt;My use case was to render components inside the Angular Material Tabs component. Despite searching online, I couldn't find any relevant resources, so I had to figure it out myself.&lt;/p&gt;

&lt;p&gt;Below is the structure we want to use to define the components that should be displayed inside the tabs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; tabs = &amp;lt;Tab[]&amp;gt;[
    {
      label: 'Tab Component',
      component: TabComponent,
      data: {
        title: 'Tab 1 Import information',
        content: `Donec lacinia condimentum efficitur. Phasellus tempor est in luctus
        facilisis.`,
      },
    },
    {
      label: 'Random component',
      component: RandomComponent,
      data: {
        text: 'Text passed on from the random component',
      },
    },
  ];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Component
&lt;/h2&gt;

&lt;p&gt;Here's the complete code snippet for the component that renders the components inside the tab container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Tab = {
  label: string;
  component: Type&amp;lt;any&amp;gt;;
  data: Record&amp;lt;string, any&amp;gt;;
};

@Component({
  selector: 'app-tabcontainer',
  standalone: true,
  imports: [MatTabsModule],
  templateUrl: './tabcontainer.component.html',
  styleUrl: './tabcontainer.component.css',
})
export class TabcontainerComponent {
  viewContainerRef = inject(ViewContainerRef);
  tabs = &amp;lt;Tab[]&amp;gt;[
    {
      label: 'Tab Component',
      component: TabComponent,
      data: {
        title: 'Tab 1 Import information',
        content: `Donec lacinia condimentum efficitur. Phasellus tempor est in luctus
        facilisis.`,
      },
    },
    {
      label: 'Random component',
      component: RandomComponent,
      data: {
        text: 'Text passed on from the random component',
      },
    },
  ];

  ngOnInit() {
    this.loadComponent(this.tabs[0]);
  }

  loadComponent(tab: Tab) {
    this.viewContainerRef.clear();
    const ref = this.viewContainerRef.createComponent&amp;lt;any&amp;gt;(tab.component);

    // Pass on the props
    for (const prop in tab.data) {
      if (Object.prototype.hasOwnProperty.call(ref.instance, prop)) {
        ref.instance[prop] = tab.data[prop];
      }
    }
  }

  onTabSelected(index: number) {
    this.loadComponent(this.tabs[index]);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Caching the tabs
&lt;/h2&gt;

&lt;p&gt;I conducted performance testing to see if caching the component references and loading them from the cache upon request would improve render time. However, there was no improvement in render time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular signals
&lt;/h2&gt;

&lt;p&gt;The code doesn't work with &lt;code&gt;input()&lt;/code&gt; signals yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/stackblitz-starters-wpgfma?file=src%2Fapp%2Ftabcontainer%2Ftabcontainer.component.ts"&gt;Try the stackblitz&lt;/a&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to implement an inline styles Content Security Policy with Angular and Nginx</title>
      <dc:creator>Ferdie Sletering</dc:creator>
      <pubDate>Sun, 13 Jun 2021 09:16:40 +0000</pubDate>
      <link>https://dev.to/ferdiesletering/how-to-implement-an-inline-styles-content-security-policy-with-angular-and-nginx-2ke2</link>
      <guid>https://dev.to/ferdiesletering/how-to-implement-an-inline-styles-content-security-policy-with-angular-and-nginx-2ke2</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;We want to make our applications as safe as possible, so we implement a content security policy(CSP) to mitigate Cross Site Scripting (XSS) attacks or Click Jacking.&lt;/p&gt;

&lt;p&gt;The demo application contains an ngx-bootstrap toggle and a Angular Material slider component.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;application&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuo2l7a0fjb71lrtyjvxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuo2l7a0fjb71lrtyjvxi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement the Content Security Policy(CSP)
&lt;/h2&gt;

&lt;p&gt;Let's implement a CSP header. More information about &lt;a href="https://content-security-policy.com/" rel="noopener noreferrer"&gt;CSP&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Security-Policy"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"default-src 'self'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result is that our application doesn't look the same anymore.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;application&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuudv8r6fwkhjlhy09lb1.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuudv8r6fwkhjlhy09lb1.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened?
&lt;/h2&gt;

&lt;p&gt;Due to our CSP policy, the browser blocks all inline styling that comes from an untrusted source.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;console.log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5csp5mye237cnavn5dt1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5csp5mye237cnavn5dt1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Angular Material and ngx-bootstrap styles are added with the styleUrls property. Angular will parse the component's styling and add them to the &lt;/p&gt; of the page. Based on the ViewEncapsulation property, it's global(none) or scoped(emulated).

&lt;p&gt;&lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5quq4s97yg3io6bpr754.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5quq4s97yg3io6bpr754.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to solve
&lt;/h2&gt;

&lt;p&gt;When we have control of our styling, we could place all our CSS into a separate file. Issue solved! However, we don't have control over how libraries handle their styling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nonce approach
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Allows an inline script or CSS to execute if the script (e.g.: &lt;code&gt;&amp;lt;style nonce=" r@nd0m"&amp;gt;&lt;/code&gt;) tag contains a nonce attribute matching the nonce specified in the CSP header. The nonce should be a secure random string and should not be reused.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's add a nonce to our CPS policy and style tags, so our inline styling comes from a trusted source.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

 &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Security-Policy"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"default-src 'self'; style-src 'self' 'nonce-random-csp-nonce';"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Add nonce to style tag
&lt;/h2&gt;

&lt;p&gt;When looking into the angular/platform-browser package, the following code is responsible for injecting the style tags.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shared_styles_host.ts&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_addStylesToHost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;styleNodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styleEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;styleNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Luckily Angular provides us with dependency providers, which allows us to create a custom _addStylesToHost function.&lt;/p&gt;

&lt;p&gt;We copy the &lt;code&gt;shared_styles_host.ts&lt;/code&gt; and modify the &lt;code&gt;_addStylesToHost&lt;/code&gt; method.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

 &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_addStylesToHost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;styleNodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styleEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nonce&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;random-csp-nonce&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Add nonce&lt;/span&gt;
      &lt;span class="nx"&gt;styleNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We create a module that can be imported in our &lt;code&gt;app.module.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;inline-styles-csp.module.ts&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CustomDomSharedStylesHost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./shared_styles_host&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ɵDomSharedStylesHost&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ɵDomSharedStylesHost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CustomDomSharedStylesHost&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InlineStylesCSPModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After applying these changes, the style tag contains a nonce.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;styletag with nonce&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frz2c11zznff6t0xz2l6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frz2c11zznff6t0xz2l6t.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now have a static nonce that is not secure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The nonce should be a secure random string and should not be reused.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Create a secure random string with Nginx
&lt;/h2&gt;

&lt;p&gt;We use the &lt;code&gt;sub_filter&lt;/code&gt; module of Nginx to replace the static with a dynamic string. In that case, we use the Nginx &lt;code&gt;$request_id&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nginx.conf&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sub_filter_once off;
sub_filter random-csp-nonce $request_id;

add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'nonce-$request_id'";


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Also, note we add the &lt;code&gt;add_header&lt;/code&gt; to our config file. &lt;/p&gt;

&lt;p&gt;Still, our solution doesn't work because Nginx replaces &lt;code&gt;random-csp-nonce&lt;/code&gt; on the index.html file. Angular adds the style tags to the document after Nginx serves the document. When we place a hard-coded &lt;code&gt;&amp;lt;style nonce="random-csp-nonce" /&amp;gt;&lt;/code&gt; in the index.html it gets replaced with a dynamic nonce.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add metatag
&lt;/h3&gt;

&lt;p&gt;We add a new metatag to the index.html so our script can look up the dynamic nonce value.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"CSP-NONCE"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"random-csp-nonce"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;app-root&amp;gt;&amp;lt;/app-root&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's update our &lt;code&gt;_addStylesToHost&lt;/code&gt; method to query the nonce.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

 &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_addStylesToHost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;styleNodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta[name="CSP-NONCE"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styleEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nonce&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Add nonce&lt;/span&gt;
      &lt;span class="nx"&gt;styleNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;styleEl&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each time we reload the page, a new random nonce is generated and applied to all style tags.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;random nonce styletag&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllvpy1qwk0cymmdgow2b.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllvpy1qwk0cymmdgow2b.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our application looks the same as from the beginning. But now, we have applied a CSP policy :).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;application&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5f1nlqfjffndtif5k9c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5f1nlqfjffndtif5k9c3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Although we have proof of concept on fixing the inline styles issue, the final and more sustainable solution should come from the community and the Angular team. For now, we have to inject a custom DomSharedStylesHost class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;The Github code contains a full version of the code. However, for demo purposes, some code is stripped out of the original code.&lt;/p&gt;

&lt;p&gt;🌎 &lt;a href="https://angular-csp.azurewebsites.net" rel="noopener noreferrer"&gt;Live demo&lt;/a&gt;&lt;br&gt;
📝 &lt;a href="https://github.com/ferdiesletering/angular-csp-nonce" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Improvements
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Nonce in style tags remains empty
&lt;/h4&gt;

&lt;p&gt;The browser parses the inline styles, but the actual nonce remains empty. I don't know why this occurs. The response Content-Security-Policy header contains the correct nonce value.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stronger nonce token
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;$request_id&lt;/code&gt; is not a  cryptographically secure random token.  We could improve this with an &lt;a href="https://github.com/openresty/set-misc-nginx-module#set_secure_random_alphanum" rel="noopener noreferrer"&gt;nginx module&lt;/a&gt; as &lt;a href="https://scotthelme.co.uk/csp-nonce-support-in-nginx/" rel="noopener noreferrer"&gt;Scott Helme&lt;/a&gt; suggests.&lt;/p&gt;

&lt;h4&gt;
  
  
  100% secure?
&lt;/h4&gt;

&lt;p&gt;The fact we use &lt;a href="https://angular.io/guide/aot-compiler" rel="noopener noreferrer"&gt;AOT&lt;/a&gt; compilation means all code is already compiled and can't be tampered with. So although the code looks for the CSP header and gets the nonce, any other script that gets executed could do the same.&lt;/p&gt;

&lt;p&gt;Any feedback or thoughts are welcome.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>nginx</category>
      <category>security</category>
    </item>
  </channel>
</rss>
