Style AEM CIF Core Components style-aem-cif-core-components

The CIF Venia Project is a reference code base for using CIF Core Components. In this tutorial, you inspect the Venia reference project and understand how CSS and JavaScript used by AEM CIF Core components are organized. You will also create a style using CSS to update the default style of the Product Teaser component.

TIP
Use the AEM Project archetype when starting your own commerce implementation.

What You Will Build

In this tutorial, a new style is implemented for the Product Teaser component that resembles a card. Lessons learned in the tutorial can be applied to other CIF Core Components.

What you will build

Prerequisites prerequisites

A local development environment is required to complete this tutorial. This includes a running instance of AEM that is configured and connected to an Adobe Commerce instance. Review the requirements and steps for setting up a local development with AEM.

Clone the Venia Project clone-venia-project

We clone the Venia Project and then override the default styles.

NOTE
Feel free to use an existing project (based on the AEM Project Archetype with CIF included) and skip this section.
  1. Run the following git command to clone the project:

    code language-shell
    $ git clone git@github.com:adobe/aem-cif-guides-venia.git
    
  2. Build and deploy the project to a local instance of AEM:

    code language-shell
    $ cd aem-cif-guides-venia/
    $ mvn clean install -PautoInstallPackage,cloud
    
  3. Add the necessary OSGi configurations to connect your AEM instance to an Adobe Commerce instance or add the configurations to the newly created project.

  4. At this point you should have a working version of a storefront that is connected to an Adobe Commerce instance. Navigate to the US > Home page at: http://localhost:4502/editor.html/content/venia/us/en.html.

    You should see that the storefront currently is using the Venia theme. Expanding the Main Menu of the storefront, you should see various categories, indicating that the connection to Adobe Commerce is working.

    Storefront Configured with Venia Theme

Client Libraries and ui.frontend Module introduction-to-client-libraries

The CSS and JavaScript responsible for rendering the theme/styles of the storefront is managed in AEM by a client library or clientlibs for short. Client libraries provide a mechanism to organize CSS and JavaScript in a project’s code and then deliver onto the page.

Brand-specific styles can be applied to AEM CIF Core Components by adding and overriding the CSS managed by these client libraries. Understanding how client libraries are structured and included on the page is critical.

The ui.frontend is a dedicated webpack project to manage all the front-end assets for a project. This allows front-end developers to use any number of languages and technologies like TypeScript, Sass and much more.

The ui.frontend module is also a Maven module and integrated with the larger project by using an NPM module the aem-clientlib-generator. During a build, the aem-clientlib-generator copies the compiled CSS and JavaScript files into a client library in the ui.apps module.

ui.frontend to ui.apps architecture

Compiled CSS and JavaScript are copied from the ui.frontend module into the ui.apps module as a client library during a Maven build

Update the Teaser Style ui-frontend-module

Next, make a small change to the Teaser style to see how the ui.frontend module and client libraries work. Use the IDE of your choice to import the Venia project. Screenshots used are from the Visual Studio Code IDE.

  1. Navigate and expand the ui.frontend module and expand the folder hierarchy to: ui.frontend/src/main/styles/commerce:

    ui.frontend commerce folder

    Notice that there are multiple Sass (.scss) files beneath the folder. These are the Commerce specific styles for each of the Commerce components.

  2. Open the file _productteaser.scss.

  3. Update the .item__image rule and modify the border rule:

    code language-scss
    .item__image {
        border: #ea00ff 8px solid; /* <-- modify this rule */
        display: block;
        grid-area: main;
        height: auto;
        opacity: 1;
        transition-duration: 512ms;
        transition-property: opacity, visibility;
        transition-timing-function: ease-out;
        visibility: visible;
        width: 100%;
    }
    

    The above rule should add a bold pink border to the Product Teaser Component.

  4. Open a new terminal window and navigate to the ui.frontend folder:

    code language-shell
    $ cd <project-location>/aem-cif-guides-venia/ui.frontend
    
  5. Run the following Maven command:

    code language-shell
    $ mvn clean install
    ...
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  29.497 s
    [INFO] Finished at: 2020-08-25T14:30:44-07:00
    [INFO] ------------------------------------------------------------------------
    

    Inspect the terminal output. You can see that the Maven command ran several NPM scripts including npm run build. The npm run build command is defined in the package.json file and has the effect of compiling the webpack project and triggering the client library generation.

  6. Inspect the file ui.frontend/dist/clientlib-site/site.css:

    Compiled Site CSS

    The file is the compiled and minified version of all the Sass files in the project.

    note note
    NOTE
    Files like this are ignored from source control since they should be generated during build time.
  7. Inspect the file ui.frontend/clientlib.config.js.

    code language-js
    /* clientlib.config.js*/
    ...
    // Config for `aem-clientlib-generator`
    module.exports = {
        context: BUILD_DIR,
        clientLibRoot: CLIENTLIB_DIR,
        libs: [
            {
                ...libsBaseConfig,
                name: 'clientlib-site',
                categories: ['venia.site'],
                dependencies: ['venia.dependencies', 'aem-core-cif-react-components'],
                assets: {
    ...
    

    This is the configuration file for aem-clientlib-generator and determines where and how the compiled CSS and JavaScript will transformed into an AEM client library.

  8. In the ui.apps module inspect the file: ui.apps/src/main/content/jcr_root/apps/venia/clientlibs/clientlib-site/css/site.css:

    Compiled Site CSS in ui.apps

    This copies the site.css file into the ui.apps project. It is now part of a client library named clientlib-site with a category of venia.site. Once the file is part of the ui.apps module it can be deployed to AEM.

    note note
    NOTE
    Files like this are also ignored from source control since they should be generated during build time.
  9. Next inspect the other client libraries generated by the project:

    Other client libraries

    These client libraries are not managed by the ui.frontend module. Instead these client libraries include CSS and JavaScript dependencies provided by Adobe. The definition for these client libraries is in the .content.xml file beneath each folder.

    clientlib-base - This is an empty client library that simply embeds the necessary dependencies from AEM Core Components. The category is venia.base.

    clientlib-cif - This is also an empty client library that simply embeds the necessary dependencies from AEM CIF Core Components. The category is venia.cif.

    clientlib-grid - This includes the CSS needed to enable AEM’s Responsive Grid feature. Using the AEM grid enables Layout Mode in the AEM Editor and gives content authors the ability to resize components. The category is venia.grid and is embedded in the venia.base library.

  10. Inspect the files customheaderlibs.html and customfooterlibs.html beneath ui.apps/src/main/content/jcr_root/apps/venia/components/page:

    Custom Header and Footer scripts

    These scripts include venia.base and venia.cif libraries as a part of all pages.

    note note
    NOTE
    Only the base libraries are “hard-coded” as part of the page scripts. venia.site is not included in these files and instead included as part of the page template for greater flexibility. This is inspected later.
  11. From the terminal, build and deploy the entire project to a local instance of AEM:

    code language-shell
    $ cd aem-cif-guides-venia/
    $ mvn clean install -PautoInstallPackage,cloud
    

Author a Product Teaser author-product-teaser

Now that the code updates have been deployed, add a new instance of the Product Teaser component to the home page of the site using the AEM authoring tools. This allows us to view the updated styles.

  1. Open a new browser tab and navigate to the Home Page of the site: http://localhost:4502/editor.html/content/venia/us/en.html.

  2. Expand the Asset finder (the side rail) in Edit mode. Switch the Asset filter to Products.

    Expand the Asset Finder and filter by Products

  3. Drag and drop a new Product onto the home page in the main Layout Container:

    Product Teaser with pink border

    You should see that the Product Teaser now has a bright pink border based on the CSS rule change created earlier.

Verify Client Libraries on the Page verify-client-libraries

Next verify the inclusion of the client libraries on the page.

  1. Navigate to the Home Page of the site: http://localhost:4502/editor.html/content/venia/us/en.html.

  2. Select the Page Information menu and click View as Published:

    View as Published

    This opens the page without any of the AEM author JavaScript loaded, as it would appear on the published site. Notice that the url has the query parameter ?wcmmode=disabled appended. When developing CSS and JavaScript, it is a good practice to use this parameter to simplify the page without anything from AEM author.

  3. View the page source and you should be able to identify several client libraries are included:

    code language-html
    <!DOCTYPE html>
    <html lang="en-US">
    <head>
        ...
        <link rel="stylesheet" href="/etc.clientlibs/venia/clientlibs/clientlib-base.min.css" type="text/css">
        <link rel="stylesheet" href="/etc.clientlibs/venia/clientlibs/clientlib-site.min.css" type="text/css">
    </head>
    ...
        <script type="text/javascript" src="/etc.clientlibs/venia/clientlibs/clientlib-site.min.js"></script>
        <script type="text/javascript" src="/etc.clientlibs/core/wcm/components/commons/site/clientlibs/container.min.js"></script>
        <script type="text/javascript" src="/etc.clientlibs/venia/clientlibs/clientlib-base.min.js"></script>
    <script type="text/javascript" src="/etc.clientlibs/core/cif/clientlibs/common.min.js"></script>
    <script type="text/javascript" src="/etc.clientlibs/venia/clientlibs/clientlib-cif.min.js"></script>
    </body>
    </html>
    

    Client libraries when delivered to the page are prefixed with /etc.clientlibs and are served via a proxy to avoid exposing anything sensitive in /apps or /libs.

    Notice venia/clientlibs/clientlib-site.min.css and venia/clientlibs/clientlib-site.min.js. These are the compiled CSS and JavaScript files derived from the ui.frontend module.

Client Library Inclusion with Page Templates client-library-inclusion-pagetemplates

There are several options for how to include a client-side library. Next inspect how the generated project includes the clientlib-site libraries via Page Templates.

  1. Navigate to the Home Page of the site within the AEM Editor: http://localhost:4502/editor.html/content/venia/us/en.html.

  2. Select the Page Information menu and click Edit Template:

    Edit the template

    This opens the Landing Page template the Home page is based on.

    note note
    NOTE
    To view all available templates from the AEM Start screen navigate to Tools > General > Templates.
  3. In the upper left-hand corner, select the Page Information icon and click Page Policy.

    Page policy menu item

  4. This opens the Page Policy for the Landing Page template:

    Page Policy - landing page

    On the right-hand side you can see a listing of client libraries categories that will be included on all pages that use this template.

    • venia.dependencies - Provides any vendor libraries that venia.site depends on.
    • venia.site - This is the category for clientlib-site that the ui.frontend module generates.

    Notice that other templates use the same policy, Content Page, Landing Page, and so on. By reusing the same policy, we can ensure that the same client libraries are included on all the pages.

    The advantage of using Templates and Page policies to manage the inclusion of client libraries is that you can change the policy per template. For example, perhaps you are managing two different brands within the same AEM instance. Each brand has its own unique style or theme but the base libraries and code will be the same. Another example, if you had a larger client library that you only wanted to appear on certain pages, you could make a unique page policy just for that template.

Local Webpack Development local-webpack-development

In the previous exercise, an update was made to a Sass file in the ui.frontend module and then after performing a Maven build the changes are deployed to AEM. Next we look at using a webpack-dev-server to rapidly develop the front-end styles.

The webpack-dev-server proxies images and some of the CSS/JavaScript from the local instance of AEM but allows the developer to modify the styles and JavaScript in the ui.frontend module.

  1. In the browser navigate to the Home page and View as Published: http://localhost:4502/content/venia/us/en.html?wcmmode=disabled.

  2. View the source of the page and the copy the raw HTML of the page.

  3. Return to the IDE of your choice beneath the ui.frontend module open the file: ui.frontend/src/main/static/index.html

    Static HTML File

  4. Overwrite the contents of index.html and paste the HTML copied in the previous step.

  5. Find the includes for clientlib-site.min.css, clientlib-site.min.js and remove them.

    code language-html
    <head>
        <!-- remove this link -->
        <link rel="stylesheet" href="/etc.clientlibs/venia/clientlibs/clientlib-base.min.css" type="text/css">
        ...
    </head>
    <body>
        ...
         <!-- remove this link -->
        <script type="text/javascript" src="/etc.clientlibs/venia/clientlibs/clientlib-site.min.js"></script>
    </body>
    

    These are removed because they represent the compiled version of the CSS and JavaScript generated by the ui.frontend module. Leave the other client libraries as they will be proxied from the running AEM instance.

  6. Open a new terminal window and navigate into the ui.frontend folder. Run the command npm start:

    code language-shell
    $ cd ui.frontend
    $ npm start
    

    This starts the webpack-dev-server on http://localhost:8080/

    note caution
    CAUTION
    If you get a Sass related error, stop the server and run the command npm rebuild node-sass and repeat the above steps. This can occur if you have a different version of npm and node then specified in the project aem-cif-guides-venia/pom.xml.
  7. Navigate to the http://localhost:8080/ in a new tab with the same browser as a logged in instance of AEM. You should see the Venia home page via the webpack-dev-server:

    Webpack dev server on port 80

    Leave the webpack-dev-server running. It is used in the next exercise.

Implement Card style for Product Teaser update-css-product-teaser

Next modify the Sass files in the ui.frontend module to implement a card-like style for the Product Teaser. The webpack-dev-server is used to rapidly see the changes.

Return to the IDE and the generated project.

  1. In the ui.frontend module, reopen the file _productteaser.scss at ui.frontend/src/main/styles/commerce/_productteaser.scss.

  2. Make the following changes to the Product Teaser border:

    code language-diff
        .item__image {
    -       border: #ea00ff 8px solid;
    +       border-bottom: 1px solid #c0c0c0;
            display: block;
            grid-area: main;
            height: auto;
            opacity: 1;
            transition-duration: 512ms;
            transition-property: opacity, visibility;
            transition-timing-function: ease-out;
            visibility: visible;
            width: 100%;
        }
    

    Save the changes and the webpack-dev-server should automatically refresh with the new styles.

  3. Add a drop-shadow and include rounded corners to the Product Teaser.

    code language-scss
     .item__root {
         position: relative;
         box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
         transition: 0.3s;
         border-radius: 5px;
         float: left;
         margin-left: 12px;
         margin-right: 12px;
    }
    
    .item__root:hover {
       box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
    }
    
  4. Update the Product’s name to appear at the bottom of the teaser and modify the text color.

    code language-css
    .item__name {
        color: #000;
        display: block;
        float: left;
        font-size: 22px;
        font-weight: 900;
        line-height: 1em;
        padding: 0.75em;
        text-transform: uppercase;
        width: 75%;
    }
    
  5. Update the Product’s price to also appear in the bottom of the teaser and modify the text color.

    code language-css
    .price {
        color: #000;
        display: block;
        float: left;
        font-size: 18px;
        font-weight: 900;
        padding: 0.75em;
        padding-bottom: 2em;
        width: 25%;
    
        ...
    
  6. Update the media query at the bottom, to stack the name and price in screens smaller than 992px.

    code language-css
    @media (max-width: 992px) {
        .productteaser .item__name {
            font-size: 18px;
            width: 100%;
        }
        .productteaser .item__price {
            font-size: 14px;
            width: 100%;
        }
    }
    

    You should now see the card-style reflected in the webpack-dev-server:

    Webpack Dev Server teaser changes

    However, the changes have not been deployed to AEM yet. You can download the solution file here.

  7. Deploy the updates to AEM using your Maven skills, from a command-line terminal:

    code language-shell
    $ cd aem-cif-guides-venia/
    $ mvn clean install -PautoInstallPackage,cloud
    
    note note
    NOTE
    There are additional IDE Setup and Tools that can sync project files directly to a local AEM instance without having to perform a full Maven build.

View Updated Product Teaser view-updated-product-teaser

After the code for the project is deployed to AEM, you should be able to see the changes to the Product Teaser.

  1. Return to your browser and refresh the Home page: http://localhost:4502/editor.html/content/venia/us/en.html. You should see the updated product teaser styles applied.

    Updated Product Teaser style

  2. Experiment by adding additional Product teasers. Use Layout Mode to change the width and offset of the components to display multiple teasers in a row.

    Multiple Product Teasers

Troubleshooting troubleshooting

You can verify in CRXDE-Lite that the updated CSS file has been deployed: http://localhost:4502/crx/de/index.jsp#/apps/venia/clientlibs/clientlib-site/css/site.css

When deploying new CSS and/or JavaScript files, it is also important to ensure that the browser is not serving stale files. You can eliminate this by clearing the browser cache or starting a fresh browser session.

AEM also attempts to cache client libraries for performance. Occasionally, following a code deployment the older files are served. You can manually invalidate AEM’s client library cache using the Rebuild Client Libraries tool. Invalidate Caches is the preferred method if you suspect AEM has cached an old version of a client library. Rebuild Libraries is inefficient and time consuming.

Congratulations congratulations

You styled your first AEM CIF Core Component and you used a webpack dev server!

Bonus Challenge bonus-challenge

Use the AEM Style system to create two styles that can be toggled on/off by a content author. Developing with the Style System includes detailed steps and information on how to accomplish this.

Bonus Challenge - style System

Additional Resources additional-resources

recommendation-more-help
19ffd973-7af2-44d0-84b5-d547b0dffee2