Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Font and Asset inclusion in Angular SPA clientlib?

Avatar

Level 1

I've been trying to create an Angular UI Library that is included in an Angular Application which is then to be used as the clientlib within AEM. But the process of building the application and then moving it to clientlibs is changing the import path within the CSS.

 

The UI library contains fonts that are packaged up along with the SCSS pointing to those relative font locations.

 

libs/ui/src/styles/fonts.scss

@Font-face {
  font-family: 'FF Mark Pro';
  font-style: normal;
  font-weight: typography.$weight-regular;
  src: url('../assets/fonts/FF-Mark-Regular.woff2') format('woff2'),
  url('../assets/fonts/FF-Mark-Regular.woff') format('woff');
}
 

libs/ui/src/assets/fonts/FF-Mark-Regular.woff
libs/ui/src/assets/fonts/FF-Mark-Regular.woff2

 

Now to include this scss I have added it as a separate style bundle in the angular.

 

"styles": [

  "apps/aem-clientlib/src/styles.scss",
  {
    "input": "libs/eds-base/src/styles/fonts.scss",
    "bundleName": "fonts"
  }
]
 
Annoyingly the way angular works is that it then rolls all the included assets in the scss file and dumps them in the root of the project, adds the <link> with the each of the css files in the index.html, and the paths in the css are now relative to those files.
 
Screenshot 2022-03-08 at 16.17.22.png
 
<link
  rel="stylesheet"
  href="fonts.94e3d1271343934c.css"
  crossorigin="anonymous"
  integrity="sha384-W9tDdK7sgsqfsHpjuDpFWdqEEfpAg9+IhEBTnixGpM4EiLKBV5Q5oQkkQqg/VhF9"
  media="print"
  onload="this.media='all'"
/>
 
dist/aem-clientlib/fonts.####.css
@Font-face {
  font-family: FF Mark Pro;
  font-style: normal;
  font-weight: 400;
  src: url(FF-Mark-Regular.1ae3f8c88007c98e.woff2) format("woff2"),
  url(FF-Mark-Regular.77d17aff63c2ea14.woff) format("woff");
}
 
Now this all works fine, but the issue comes when I try to use the aem-clientlib-generator to move the files to the aem application, the files split and then the link between the css and fonts is broken.
 
Screenshot 2022-03-08 at 16.28.11.png
 
Is there a way to correctly import the scss so that the paths are then changed to point to the resources folder?
1 Accepted Solution

Avatar

Correct answer by
Administrator

Check "Add Styles with Sass" section: https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-with-aem-headless/s... 

 

//

Next, some style updates will be added to the project. This project will add Sass support for a few useful features like variables.

  1. Open a terminal window and stop the webpack dev server if started. From inside the ui.frontend folder enter the following command to update the Angular app to process .scss files.

    $ cd ui.frontend
    $ ng config schematics.@schematics/angular:component.styleext scss
    

    This will update the angular.json file with a new entry at the bottom of the file:

    "schematics": {
        "@schematics/angular:component": {
        "styleext": "scss"
        }
    }
    
  2. Install normalize-scss to normalize the styles across browsers:

    $ npm install normalize-scss --save
    
  3. Return to the IDE and beneath ui.frontend/src create a new folder named styles.

  4. Create a new file beneath ui.frontend/src/styles named _variables.scss and populate it with the following variables:

    //_variables.scss
    
    //== Colors
    //
    //## Gray and brand colors for use across theme.
    
    $black:                  #202020;
    $gray:                   #696969;
    $gray-light:             #EBEBEB;
    $gray-lighter:           #F7F7F7;
    $white:                  #FFFFFF;
    $yellow:                 #FFEA00;
    $blue:                   #0045FF;
    
    
    //== Typography
    //
    //## Font, line-height, and color for body text, headings, and more.
    
    $font-family-sans-serif:  "Helvetica Neue", Helvetica, Arial, sans-serif;
    $font-family-serif:       Georgia, "Times New Roman", Times, serif;
    $font-family-base:        $font-family-sans-serif;
    $font-size-base:          18px;
    
    $line-height-base:        1.5;
    $line-height-computed:    floor(($font-size-base * $line-height-base));
    
    // Functional Colors
    $brand-primary:             $yellow;
    $body-bg:                   $white;
    $text-color:                $black;
    $text-color-inverse:        $gray-light;
    $link-color:                $blue;
    
    //Layout
    $max-width: 1024px;
    $header-height: 75px;
    
    // Spacing
    $gutter-padding: 12px;
    
  5. Re-name the extension of the file styles.css at ui.frontend/src/styles.css to styles.scss. Replace the contents with the following:

    /* styles.scss * /
    
    /* Normalize */
    @import '~normalize-scss/sass/normalize';
    
    @import './styles/variables';
    
    body {
        background-color: $body-bg;
        font-family: $font-family-base;
        margin: 0;
        padding: 0;
        font-size: $font-size-base;
        text-align: left;
        color: $text-color;
        line-height: $line-height-base;
    }
    
    body.page {
        max-width: $max-width;
        margin: 0 auto;
        padding: $gutter-padding;
        padding-top: $header-height;
    }
    
  6. Update angular.json and re-name all references to style.css with styles.scss. There should be 3 references.

      "styles": [
    -    "src/styles.css"
    +    "src/styles.scss"
       ],
    

Update Header styles

Next, add some brand-specific styles to the Header component using Sass.

  1. Start the webpack dev server to see the styles updating in real-time:

    $ npm run start:mock
    
  2. Under ui.frontend/src/app/components/header re-name header.component.css to header.component.scss. Populate the file with the following:

    @import "~src/styles/variables";
    
    .header {
        width: 100%;
        position: fixed;
        top: 0;
        left:0;
        z-index: 99;
        background-color: $brand-primary;
        box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.24);
    }
    
    .header-container {
        display: flex;
        max-width: $max-width;
        margin: 0 auto;
        padding-left: $gutter-padding;
        padding-right: $gutter-padding;
    }
    
    .logo {
        z-index: 100;
        display: flex;
        padding-top: $gutter-padding;
        padding-bottom: $gutter-padding;
    }
    
    .logo-img {
        width: 100px;
    }
    
  3. Update header.component.ts to reference header.component.scss:

    ...
      @Component({
        selector: 'app-header',
        templateUrl: './header.component.html',
    -   styleUrls: ['./header.component.css']
    +   styleUrls: ['./header.component.scss']
      })
    ...
    
  4. Return to the browser and the webpack dev server:



Kautuk Sahni

View solution in original post

1 Reply

Avatar

Correct answer by
Administrator

Check "Add Styles with Sass" section: https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-with-aem-headless/s... 

 

//

Next, some style updates will be added to the project. This project will add Sass support for a few useful features like variables.

  1. Open a terminal window and stop the webpack dev server if started. From inside the ui.frontend folder enter the following command to update the Angular app to process .scss files.

    $ cd ui.frontend
    $ ng config schematics.@schematics/angular:component.styleext scss
    

    This will update the angular.json file with a new entry at the bottom of the file:

    "schematics": {
        "@schematics/angular:component": {
        "styleext": "scss"
        }
    }
    
  2. Install normalize-scss to normalize the styles across browsers:

    $ npm install normalize-scss --save
    
  3. Return to the IDE and beneath ui.frontend/src create a new folder named styles.

  4. Create a new file beneath ui.frontend/src/styles named _variables.scss and populate it with the following variables:

    //_variables.scss
    
    //== Colors
    //
    //## Gray and brand colors for use across theme.
    
    $black:                  #202020;
    $gray:                   #696969;
    $gray-light:             #EBEBEB;
    $gray-lighter:           #F7F7F7;
    $white:                  #FFFFFF;
    $yellow:                 #FFEA00;
    $blue:                   #0045FF;
    
    
    //== Typography
    //
    //## Font, line-height, and color for body text, headings, and more.
    
    $font-family-sans-serif:  "Helvetica Neue", Helvetica, Arial, sans-serif;
    $font-family-serif:       Georgia, "Times New Roman", Times, serif;
    $font-family-base:        $font-family-sans-serif;
    $font-size-base:          18px;
    
    $line-height-base:        1.5;
    $line-height-computed:    floor(($font-size-base * $line-height-base));
    
    // Functional Colors
    $brand-primary:             $yellow;
    $body-bg:                   $white;
    $text-color:                $black;
    $text-color-inverse:        $gray-light;
    $link-color:                $blue;
    
    //Layout
    $max-width: 1024px;
    $header-height: 75px;
    
    // Spacing
    $gutter-padding: 12px;
    
  5. Re-name the extension of the file styles.css at ui.frontend/src/styles.css to styles.scss. Replace the contents with the following:

    /* styles.scss * /
    
    /* Normalize */
    @import '~normalize-scss/sass/normalize';
    
    @import './styles/variables';
    
    body {
        background-color: $body-bg;
        font-family: $font-family-base;
        margin: 0;
        padding: 0;
        font-size: $font-size-base;
        text-align: left;
        color: $text-color;
        line-height: $line-height-base;
    }
    
    body.page {
        max-width: $max-width;
        margin: 0 auto;
        padding: $gutter-padding;
        padding-top: $header-height;
    }
    
  6. Update angular.json and re-name all references to style.css with styles.scss. There should be 3 references.

      "styles": [
    -    "src/styles.css"
    +    "src/styles.scss"
       ],
    

Update Header styles

Next, add some brand-specific styles to the Header component using Sass.

  1. Start the webpack dev server to see the styles updating in real-time:

    $ npm run start:mock
    
  2. Under ui.frontend/src/app/components/header re-name header.component.css to header.component.scss. Populate the file with the following:

    @import "~src/styles/variables";
    
    .header {
        width: 100%;
        position: fixed;
        top: 0;
        left:0;
        z-index: 99;
        background-color: $brand-primary;
        box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.24);
    }
    
    .header-container {
        display: flex;
        max-width: $max-width;
        margin: 0 auto;
        padding-left: $gutter-padding;
        padding-right: $gutter-padding;
    }
    
    .logo {
        z-index: 100;
        display: flex;
        padding-top: $gutter-padding;
        padding-bottom: $gutter-padding;
    }
    
    .logo-img {
        width: 100px;
    }
    
  3. Update header.component.ts to reference header.component.scss:

    ...
      @Component({
        selector: 'app-header',
        templateUrl: './header.component.html',
    -   styleUrls: ['./header.component.css']
    +   styleUrls: ['./header.component.scss']
      })
    ...
    
  4. Return to the browser and the webpack dev server:



Kautuk Sahni