Using client extensions, you can extend Liferay without deploying OSGi modules. Just like traditional module development, client extensions live in a Liferay Workspace. Get started by learning
The required tools to begin developing client extensions
How to define a client extension in its configuration file
Client extension development follows a workspace plus project model. Within a Liferay workspace, you implement a client extension project under [workspace-root]/client-extensions. The project’s client-extension.yaml file defines its client extensions, and a build process results in a single set of outputs for each project. The built client extension project is a deployable *.zip archive called a Liferay Universal File Format Archive (LUFFA).
Client extensions grouped in a single project comprise a single, deployable unit when built. You can group client extensions where it makes sense (e.g., to improve efficiency when they should work on related tasks), but there are restrictions.
Because all client extensions in a single project are associated with a Docker container that represents a workload particular to that project, only certain kinds of client extensions are compatible for grouping. For example, microservice client extensions can only be grouped with configuration client extensions, as microservices represent a workload that runs outside Liferay.
You can group client extensions together in these ways:
Client extensions of the same type (e.g., multiple batch client extensions)
Configuration client extensions with batch client extensions
Configuration client extensions with frontend client extensions
Configuration client extensions with microservice client extensions
Building a project with an incompatible grouping of client extensions (e.g., frontend with microservice) fails with an error.
Client extensions are defined in client-extension.yaml files with these properties:
name: Enter the name as it appears in the Liferay UI. If it’s not configurable in the UI, the name value is not used.
type: Set the client extension’s type (e.g., themeCSS). The type determines how Liferay handles the client extension when it’s deployed.
dxp.lxc.liferay.com.virtualInstanceId: Enter the virtual instance ID to deploy to. This property is incompatible with Liferay PaaS.
Each client extension project has its own folder inside the workspace’s client-extensions/ folder. A client extension project contains a single client-extension.yaml file that defines one or more client extensions. For example, the iframe-2 project’s client-extension.yaml defines three iframe client extensions: Baseball, Football, and Hockey.
Depending on the type of client extension you’re using (and the kind of environment you run it in), you can also use other files to configure the client extension’s structure or container. For example, use a Dockerfile to configure the container for a custom microservice. See Packaging Client Extensions for more information.
When you build a client extension, files are created automatically and packaged in the resulting LUFFA. Define an assemble block in your client-extension.yaml file to configure files to include from your build or project files.
The assembleClientExtension Gradle task executes when you run gradle build or gradle deploy within a client extension project. During execution, the files specified in the project’s assemble block are placed into a build/liferay-client-extension-build/ folder in your project. Everything in this folder is used to create the LUFFA (e.g., dist/my-client-extension-project.zip).
Note
If your client extension project contains a package.json file with a build script defined, the script automatically executes when you build your project. This part of the build happens before files are copied, so you can specify the task’s output location in your assemble block.
The assemble block is a YAML array that can include multiple instructions for files to include. Each set of instructions follows this pattern:
- from: [some folder in your project]
include: [single file or glob match]
into: [output location in archive]
The assemble array has these properties:
from: Specify the folder from which to copy files into your client extension archive.
include: Specify a single file or glob matching a subset of files to include from the from directory. If not defined, all files are included recursively (equivalent to **/*).
You can use an array of multiple include patterns if needed:
into: Specify where in the resulting LUFFA to copy the matching resources.
Static resources for frontend client extensions must be copied into the static/ directory. Liferay serves these as static resources in self-hosted instances, or from containers in Liferay SaaS.
JSON resources for batch client extensions must be copied into the batch/ directory.
fromTask: Instead of from, you can specify a Gradle task in the project to execute before the assembly step.
For example, in a microservice client extension project using Spring Boot, the Gradle task bootJar creates the .jar file containing the application and all its dependencies. In this case use the property fromTask to trigger the execution of the project’s bootJar Gradle task and then include the outputs of the task (i.e., the built .jar file) in the root of the resulting LUFFA:
assemble:
- fromTask: bootJar
You can execute other commands with fromTask as part of your build (like building code written in other programming languages) by defining a Gradle exec task in your project’s build.gradle file.
Client extensions are built into deployable .zip archives. Each client extension archive contains a JSON file with the client extension’s settings.
Deploy client extensions by placing the .zip files in the correct location for your Liferay installation. The exact commands you’ll use depend on how your Liferay instance is hosted.
This method does not work to deploy client extensions to Liferay PaaS.
To deploy client extensions for Liferay SaaS,
Go to your workspace’s client-extensions/ folder and run
../gradlew clean build
The compiled .zip files are created in each project’s dist/ folder. To build one project at a time, run the command from the project’s folder.
Run this command to deploy each client extension to your chosen environment:
lcp deploy --extension [extension-zip-file]
When prompted, select a project and the deployment environment. The zip files are uploaded to your Liferay SaaS project once the command completes.
Note
Deploying many client extensions at the same time through the console can temporarily increase API resource usage. In some environments, this can cause the deployment to fail even when the client extensions are valid.
If a bulk deployment fails, deploy the client extensions individually or in smaller batches.
For any non-production environments, configure your web server service to allow client extensions to bypass the basic authentication requirement.
Important
Non-production environments in Liferay PaaS require special configuration for client extensions to work and authenticate properly with Liferay DXP. See Configuring Liferay PaaS for Client Extensions for more information.
After you’ve confirmed that your project is properly configured, follow these steps to deploy client extensions:
Commit the client extensions in your project’s Git repository (in your Liferay service workspace’s client-extensions/ folder).
If the Liferay workspace in your repository does not have a client-extensions/ folder, add one and put your client extensions in it.
Client extensions use the client extension pipeline to create a build exclusively for them, independent from your other services. If your build includes changes for both client extension services and other services, the two different pipelines each create a build on the Builds page that you can deploy separately.
Once the build is complete, go to your Builds page and deploy the build to your desired environment like any other build.
When the deployment completes, your client extensions appear in the chosen environment as new services.
If you self-host your Liferay installation, use the workspace bundle zip to deploy your client extensions. To build and deploy your client extensions, run this command from your workspace’s client-extensions/ folder:
../gradlew clean distBundleZip
If you must manually deploy the zip files, run
../gradlew clean build
Then copy the archives from each project’s dist/ folder into the server’s [Liferay Home]/osgi/client-extensions/ folder.
Client extensions are portable: you should never hard-code environment-specific details like domain name, network address, or Liferay’s domains. Client extensions can find context-sensitive information about their context at runtime.
Every client extension workload is provided with a set of routes containing important context-sensitive metadata automatically. With this routes-based approach, application logic can retrieve context sensitive information uniformly, regardless of where it is invoked. You must only point your client extension projects to it.
A route is a directory structure containing a set of key/value pairs. File names are the keys, and the file contents are the values. The directory structure is ignored and the directory path is the value of an environment variable. It follows the same pattern as Kubernetes configMaps.
The environment variable you use can point to one of two types of routes:
LIFERAY_ROUTES_DXP: The directory path to the route with context-sensitive metadata for the Liferay virtual instance where it’s deployed.
Here is an example of the LIFERAY_ROUTES_DXP route:
.
# A newline-separated list of every domain belonging to the DXP virtual instance
├── com.liferay.lxc.dxp.domains
# The primary domain ("Virtual Host" field) of the DXP virtual instance
├── com.liferay.lxc.dxp.main.domain
# The protocol with which to communicate with DXP virtual instance (http or https)
└── com.liferay.lxc.dxp.server.protocol
LIFERAY_ROUTES_CLIENT_EXTENSION: The directory path to the route which contains context-sensitive metadata for the client extension project itself.
Containers in Liferay Cloud have these environment variables set automatically. The routes are mounted automatically into the containers at the paths the environment variables define.
When using Liferay Workspace’s Exec, JavaExec, and NodeExec Gradle tasks, these environment variables are given default values automatically. It uses these default values:
The environment variables use the liferay.workspace.home.dir property in your Liferay workspace for your Liferay home directory, and default to indicate your default Liferay virtual instance. Define these environment variables with a specific virtual instance ID instead of default to point to it instead.
Note
If you have a Liferay workspace version before 9.0.2, you must define these environment variables yourself, following the same form.
These two environment variables must be provided to client extension processes when they are invoked to access the metadata.
This website uses cookies and similar tools, some of which are provided by third parties (together “tools”). These tools enable us and the third parties to access and record certain user-related and activity data and to track your interactions with this website. These tools and the informationcollected are used to operate and secure this website, enhance performance, enable certain website features and functionality, analyze and improve website performance, and personalize user experience.
If you click “Accept All”, you allow the deployment of all these tools and collection of the information by us and the third parties for all these purposes.
If you click “Decline All” your IP address and other information may still be collected but only by tools (including third party tools) that are necessary to operate, secure and enable default website features and functionalities. Review and change your preferences by clicking the “Configurations” at any time.
Visit our Privacy Policy