Introduction
Customizing the user interface in Liferay can be done in many ways, but doing so without touching the core code is essential for easier upgrades and maintenance. In this post, we'll look at two popular techniques for changing the design of Liferay: CSS Client Extension and Theme CSS Client Extension, and discuss how you can use them to adjust Liferay's appearance.
Prerequisites
Liferay 7.4+
Difference Between CSS and Theme CSS Client Extensions
Feature | CSS Client Extension | Theme CSS Client Extension |
---|---|---|
Scope | Applies globally across the entire Liferay instance, regardless of the theme. | Applies only to a specific theme in Liferay. |
Use Case | Ideal for making global UI changes, fixing styling issues, or adding CSS across multiple pages and themes. | Best for theme-specific customizations, such as modifying colors, fonts, or layouts for a particular theme. |
Deployment | Deployed as a general client extension, loaded at runtime for all themes. | Deployed as part of a specific theme's customization, ensuring styles apply only when that theme is active. |
Flexibility | More flexible as it works across all themes. | Limited to a single theme, requiring different extensions for multiple themes. |
Upgrade-Safety | Does not modify core Liferay files, making upgrades safer. | Also upgrade-safe but dependent on the theme it is linked to. |
Potential Conflicts | May cause unintended styling conflicts if multiple CSS extensions are applied. | Less chance of conflicts since styles are tied to a specific theme. |
Creating CSS Client Extension
You can create the client extension in two ways:
- Using Liferay's client extension admin panel
- Using Blade CLI
Using Liferay's client extension admin panel:
- Open the Global Menu (
), on the Applications tab, and click on Client Extensions.
- To create new client extension, click on the Plus (
) and select Add CSS from the dropdown.

- Provide the name and description of the CSS.
- In the CSS URL field, you can define a custom stylesheet by either providing an external CSS link or uploading your CSS file directly to Documents & Media and add link to your CSS file.
- The Source Code URL refers to the location where the source files of the client extension are hosted. This is typically used for debugging, sharing, or version control purposes. It allows developers and administrators to trace the files' origin or review its implementation. (e.g.
https://github.com/learnory/learnory-portal
)

Using Blade CLI
Note:
If you're using Liferay workspace, you must use at least version 10.1.1
of the workspace plugin, com.liferay.gradle.plugins.workspace
. Set this in the settings.gradle
file at the root of the workspace.
classpath group: "com.liferay", name: "com.liferay.gradle.plugins.workspace", version: "10.1.1"
Creating the Client Extension
- Run the command
blade samples client-extensions -l
from the root directory of your Liferay workspace to display all available client extensions. - To create CSS client extension, run
blade samples client-extensions liferay-sample-global-css-1
command, which will create both the client-extensions folder and the sample global CSS client extension inside it.
All configurations of all types of client extensions are placed in client-extension.yaml
file. Let's modify the content of it.
learnory-global-css:
name: Learnory Global CSS
type: globalCSS
url: global.*.css
The client extension with the ID learnory-global-css
defines the main configurations for a global CSS client extension, including its scope, type, and the URL to the associated CSS file.
It also contains assemble
block:
assemble:
- from: assets
hashify: global.css
into: static
Everything in the assets/
folder should be included as a static resource in the built client extension .zip
file. The hashify
property appends a unique hash value to the filename (.g., global.<hash>.css
). This ensures that browsers do not cache outdated versions of the file, allowing the latest styles to be applied automatically without requiring users to manually clear their cache.
The assets/global.css
file contains this CSS:
.btn-primary {
border: 0;
border-radius: 0.5rem;
color: var(--brand-color-3);
padding: var(--spacer-3) var(--spacer-4);
background: #f8f8ff;
box-shadow: -14px -14px 30px 0 #fff, 14px 14px 30px 0 #1d0dca17;
font-weight: var(--font-weight-semi-bold);
}
Deploy the Client Extension
Run following command from the Liferay workspace:
./gradlew clean deploy -p client-extensions/learnory-global-css
Using the Client Extension on a Page
You can configure globalCSS
client extension on all pages or specific page.
- Go to Site Menu (
) → Content & Data → Pages and click on the Configuration (
) under option menu (
).
- Scroll down to the CSS Client Extensions section at the bottom of the page and click the Add CSS Client Extensions button.

- Select your CSS client extension from the pop up and click Add.
The client extension is now set up. The background color of the button is now the color you specified in the CSS.

Using CSS Client Extension throughout the Instance
Liferay DXP 2025.Q1+/Portal GA132+
To apply a CSS Client Extension across all pages of a Liferay instance, including admin pages, set its scope
property to company
. A company-scoped CSS Client Extension is automatically applied to all instance pages upon deployment, eliminating the need for manual activation through the Liferay user interface.
learnory-global-css:
name: Learnory Global CSS
scope: company
type: globalCSS
url: global.*.css
Note:
The scope
property for a CSS Client Extension can only be configured in a workspace-based client extension project. When creating a client extension through the Liferay UI, the scope cannot be set—such extensions are always page-scoped and can only be used on site pages. The default is layout
, and applies only to site pages as set by the administrator.
Creating Theme CSS Client Extension
Imagine being able to transform the visual identity of your web page with just a few lines of code. That's exactly what a theme CSS client extension offers. By leveraging this powerful tool, you can effortlessly override the default CSS files (main.css
and clay.css
) of your current theme, unlocking a world of possibilities to redefine the look and feel of your page.
You can create the client extension in two ways:
- Using Liferay's client extension admin panel
- Using Blade CLI
Using Liferay's client extension admin panel:
- Open the Global Menu (
), on the Applications tab, and click on Client Extensions.
- To create new client extension, click on the Plus (
) and select Add Theme CSS from the dropdown.

- Provide the name and description of the CSS.
- In the Main CSS URL, Main RTL CSS URL, Clay CSS URL and Clay RTL CSS URL fields, you can define a custom stylesheet by uploading your specific CSS files directly to Documents & Media and add your CSS files link here.
- You can also include a Frontend Token Definition JSON file to configure and manage design tokens used within Style Books, enabling consistent and customizable theming across your site.
- The Source Code URL refers to the location where the source files of the client extension are hosted. This is typically used for debugging, sharing, or version control purposes. It allows developers and administrators to trace the files' origin or review its implementation. (e.g.
https://github.com/learnory/learnory-portal
)

Using Blade CLI
Note:
If you're using Liferay workspace, you must use at least version 10.1.1
of the workspace plugin, com.liferay.gradle.plugins.workspace
. Set this in the settings.gradle
file at the root of the workspace.
classpath group: "com.liferay", name: "com.liferay.gradle.plugins.workspace", version: "10.1.1"
Creating the Client Extension
- Run the command
blade samples client-extensions -l
from the root directory of your Liferay workspace to display all available client extensions. - To create CSS client extension, run
blade samples client-extensions liferay-sample-theme-css-2
command, which will create both the client-extensions folder and the sample theme CSS client extension inside it.
All configurations of all types of client extensions are placed in client-extension.yaml
file. Let's modify the content of it.
learnory-theme-css:
clayRTLURL: css/clay_rtl.css
clayURL: css/clay.css
mainRTLURL: css/main_rtl.css
mainURL: css/main.css
name: Learnory Theme CSS
type: themeCSS
The client extension with the ID learnory-theme-css
defines the main configurations for a theme CSS client extension, including its scope, type, and all the URLs to the associated CSS files.
It also contains assemble
block:
assemble:
- from: build/buildTheme/img
into: static/img
- from: build/buildTheme/images
into: static/images
These directives ensure that when the theme CSS client extension is built, all required images used in the CSS are properly packaged as static resources in Liferay. The images provided by the base theme, referenced in the package.json
file, are assembled from the build/buildTheme/images
directory and are essential for the base theme's CSS. Additionally, images from build/buildTheme/img
are sourced directly from the client extension's src/img
folder, ensuring that all necessary assets are included in the final build.
The package.json
file contains the following code:
{
"liferayDesignPack": {
"baseTheme": "styled"
},
"main": "package.json",
"name": "learnory-theme-css",
"version": "0.1.0"
}
The liferayDesignPack
section in the package.json
file specifies the base theme that the styles will build upon. By using the styled
base theme, you ensure that existing styles applied to pages, fragments, and widgets remain unaffected. Additionally, the main
, name
, and version
fields in this section provide essential metadata required for defining and managing the client extension.
Note:
You can configure the base theme for your theme CSS client extension as either unstyled
or styled
. The unstyled
theme provides only the most essential base styles, while the styled
theme builds upon it with a more comprehensive set of default Liferay styles. All Liferay themes are ultimately based on one of these two foundational themes.
When you apply a theme CSS client extension to a page using a different theme, its styles will override the original theme's styles. To preserve any custom styles from your existing theme, ensure they are included in the _custom.scss
file—this helps maintain visual consistency after applying the client extension.
Note that if you change the theme of a page that is already using a theme CSS client extension, the client extension will be removed automatically.
The src/css/_custom.scss
file contains this SCSS:
.control-menu {
background: linear-gradient(
105deg,
#003f5b,
#2b4b7d,
#5f5195,
#98509d,
#cc4c91,
#f25375,
#ff6f4e,
#ff9913
) !important;
}
.control-menu-level-1-heading {
color: #fff !important;
}
Note:
Your custom styles are written inside the _custom.scss
file, while the client-extension.yaml
file references the compiled clay.css
and main.css
. This is because the theme CSS client extension triggers the full Clay CSS build process, which compiles all SCSS files—including _custom.scss
—into the final clay.css
and main.css
. These compiled files are then used by Liferay to apply the complete styling, ensuring your custom styles are seamlessly integrated with the Clay framework.
Deploy the Client Extension
Run following command from the Liferay workspace:
./gradlew clean deploy -p client-extensions/learnory-theme-css
Using the Client Extension on a Page
You can configure themeCSS
client extension on all pages or specific page.
- Go to Site Menu (
) → Content & Data → Pages and click on the Configuration (
) under option menu (
).
- Scroll down to the Theme Client Extensions section at the bottom of the page and click the Plus button.

On the page, you can view the applied header CSS, which reflects the styles defined in your theme CSS client extension.
Using the Client Extension on Admin Pages
Set the theme CSS client extension's scope
property to controlPanel
to override the default CSS of the admin theme applied to the instance. This ensures your custom styles are applied across all admin pages within Liferay. These pages are used for content creation and system configuration, such as those accessible through the Site Menu and Global Menu.
learnory-theme-css:
clayRTLURL: css/clay_rtl.css
clayURL: css/clay.css
mainRTLURL: css/main_rtl.css
mainURL: css/main.css
name: Learnory Theme CSS
scope: controlPanel
type: themeCSS
Once deployed, you can navigate to any admin page within the instance to verify that your custom styles have been successfully applied.

Conclusion
Both CSS Client Extensions and Theme CSS Client Extensions offer upgrade-safe methods to customize Liferay without the need to alter core files. Your choice will depend on whether you need a global style adjustment or a theme-specific tweak. By understanding the pros and cons of each method, you can make an informed decision that fits your Liferay customization needs.