How to use separate CSS by Component in React Widget Liferay

When we generate a React Widget project for Liferay DXP from Yeoman (liferay-js template), you can see, in the scaffolding, we have the CSS file in assets/css folder with the style.css file (set to load on our portlet-header, in the package.json). 

It is common, in a native React application to have the CSS separated by components. So to have the CSS separated by components in a Liferay React Application, we need to apply some configurations. 

Why? 

Because in a Liferay React Application we are working with a Structure of OSGi Bundles Containing NPM Packages, for this reason you have this style.css file loaded by a portlet-header  by default, and if you try to use a separate CSS by component it won’t work and you will get an error. 

So you're thinking that when a developer wants to add a separate style file, they always need to import the css file for the style.css, right? Yes and no... so you must be asking yourself “How can I have my components and css modularized in this Liferay React Widget?”

The answer is: with “css-loader”. In this tutorial we see the few steps to do this.

Requirements: Node, Yeoman and NPM Installed

1. First, it is necessary to install liferay-js by running this command:

     npm install -g generator-liferay-js

 

2. Run the generator inside your “liferay-workspace/modules” or some other project folder which you are using

     yo liferay-js

 

3. Choose the “React Widget” type and fill in the rest of the information needed:


 

4. Inside src create a CSS file “AppComponent.css” and add the following style:

.pink-background{
    background-color: pink;
}

 

5. Open AppComponent.js file from source and add at the first div the className “pink-background” and save it.

6. Now we need to install the liferay-npm-bundler-loader-css-loader, which will convert CSS files to JavaScript modules and when the application is on the page will download it as CSS files from the server.

npm install --save-dev liferay-npm-bundler-loader-css-loader

 

7. Now to do the configuration for works the CSS by URL you need to set the “source” and “rules” in .npmbundlerrc, adding the follow it code:

"sources" : ["src", "assets"],

"rules": [

{"test": "\\.css$",

"use": ["css-loader"]

}]

 

8. The final .npmbundlerrc file should look like this:


 

9. Now deploy it, executing :

npm run deploy

 

10. Add the application to Liferay Portal’s page and now you should see your separated CSS working on.

Good to Know… differences between “...css-loader” and “...style-loader”: If you want to inject the styles inside the HTML’s DOM from your component instead of having the CSS file separated downloading you can use the “liferay-npm-bundler-loader-style-loader”.  You only need to change the step 6 and 7 from this tutorial for theses steps below:

11. Now we need to install the liferay-npm-bundler-loader-style-loader, which will convert CSS files to JavaScript modules and inject inside HTML when required.

   npm install --save-dev liferay-npm-bundler-loader-style-loader

 

12. Now to do the configuration for works the CSS by URL you need to set the “source” and “rules” in .npmbundlerrc, adding the follow it code:

"sources" : ["src", "assets"],

"rules": [

{

"test": "\\.css$",

"use": ["style-loader"]

}]

 

 13. The final .npmbundlerrc file should look like this:


 

Pretty easy :) , huh?