loading...

. . . . . .

Let’s make something together

Give us a call or drop by anytime, we endeavour to answer all enquiries within 24 hours on business days.

Find us

504, Gala Empire,
Driver-in Road, Thaltej,
Ahmedabad – 380054.

Email us

For Career – career@equalefforts.com
For Sales – sales@equalefforts.com
For More Info – info@equalefforts.com

Phone support

Phone: +91 6357 251 116

Creating a React Liferay Client Extension(with Vite)

  • By Abhishek Ramanandi
  • November 29, 2025
  • 18 Views

To create a React client extension in Liferay using Vite, you begin by setting up a React app and converting it into a web component. After configuring it with basic metadata, the extension can be deployed and added to any Liferay page for seamless integration.

Create a New React App Using Vite

yarn create vite react-chat-app --template react

Or with npm

npm create vite@latest react-chat-app -- --template react

For creating React client extensions for running it in Liferay, you may refer to:

https://liferay.dev/es/blogs/-/blogs/from-react-app-to-react-client-extension-in-5-easy-steps

If you’re not in the mood for a long read and just want to dive in, stick with me — I’ve laid out the steps. But if you enjoy the scenic route with all the details, the official guide above is your best travel buddy.

Change connecting logic – Update the main.jsx

import App from "./App"; // Ensure App is correctly imported
import { ELEMENT_NAME } from "./commons/constants";
import React from "react";
import { createRoot } from "react-dom/client";

class WebComponent extends HTMLElement {
  appLoaded = false;

  constructor() {
    super();
    this.appLoaded = false;
  }

  connectedCallback() {
    if (!this.appLoaded) {
      this.appLoaded = true;
      this.root = createRoot(this); // Use createRoot
      this.root.render(<App accessTokenParamProps={accessTokenParamProps} />);
    }
  }
}

if (!customElements.get(ELEMENT_NAME)) {
  customElements.define(ELEMENT_NAME, WebComponent);
}

Note: I have added the “react-chat-app” name in the constants.js file under the common folder. You may keep it as a static string as well.

Update index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script type="module" crossorigin src="/o/react-chat-app/assets/index-CAlfPsPC.js"></script>
    <link rel="stylesheet" crossorigin href="/o/react-chat-app/assets/index-Cs9mLtrU.css">
  </head>
  <body>
    <react-chat-app></react-chat-app>
  </body>
</html>

 Note: Make sure to add react-chat-app as a tag to ensure the React application runs properly.

Create a client-extension.yaml file

assemble:
    - from: vite-build
      into: static
react-chat-app:
#     cssURLs:
#         - assets/*.css
    friendlyURLMapping: react-chat-app
    htmlElementName: react-chat-app
    instanceable: true
    name: React Chat App

    portletCategoryName: category.client-extensions
    type: customElement
    urls:
        - assets/*.js
    useESM: true

Note: I have commented the code for CSS as I am loading CSS from the theme, you may uncomment and pass the CSS here as well.

Update Vite Configuration

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  base: '/o/react-chat-app/',
  plugins: [
    react({
      jsxRuntime: 'classic', 
    }),
  ],
  build: {
    outDir: './vite-build',
    rollupOptions: {
      external: [],
    },
  },
});

Place the react-chat-app in the client extension folder under your workspace.

For reference, here’s the file structure

Run the React client extension

In a terminal window open to client-extensions/my-react-custom-element, we’re going to issue the command:

../../gradlew clean deploy

If it’s deployed successfully, then you will get your React client extension deployed on the Liferay server, also after this, put it on a page wherever you want.

Leave a Reply

Your email address will not be published. Required fields are marked *