Skip to main content

The Ultimate Guide to Liferay DXP Performance Tuning: Speed Up Your Portal

The Ultimate Guide to Liferay DXP Performance Tuning: Speed Up Your Portal In the enterprise web space, milliseconds equal millions. Whether you are running a B2B commerce storefront, a customer support portal, or an employee intranet on Liferay DXP, slow load times will devastate your user experience and destroy your SEO rankings. Out of the box, Liferay is configured to run on almost any machine. This means its default settings are highly conservative to ensure compatibility, not maximum performance. If you are launching a production environment without tuning your server, you are leaving massive amounts of speed and scalability on the table. In this comprehensive, deep-dive guide, we are going to explore the critical layers of Liferay performance tuning. We will cover backend Java Virtual Machine (JVM) configuration, Database Connection Pooling, Elasticsearch optimization, and Frontend caching strategies. By the end of this guide, you will have a blazing-fast, enterprise-grade...

A Beginner's Guide to Liferay APIs: Fetching Data with Simple JavaScript

A Beginner's Guide to Liferay APIs: Fetching Data with Simple JavaScript



If you have been working with Liferay, you already know it is an incredible platform for managing content, building websites, and organizing user data. But what happens when you want to take the data stored inside Liferay and show it on a completely different, external website?

For example, what if you have a simple HTML landing page, and you want to display the latest news articles from your Liferay portal right on that page?

In the past, doing this required complex server-side coding and a deep understanding of Java. Today, thanks to Liferay's Headless APIs, you can accomplish this using basic HTML and a little bit of JavaScript. In this comprehensive, beginner-friendly guide, we are going to learn what an API is, how Liferay handles them, and how to write the code to connect your external page to your Liferay database.


Understanding the Basics: What is an API?

Before we look at the code, let's understand the concept. API stands for Application Programming Interface. That sounds highly technical, but it is actually a very simple concept.

Imagine you are sitting at a restaurant. You look at the menu and decide you want a burger. You don't go into the kitchen and cook the burger yourself. Instead, you tell the waiter what you want. The waiter takes your request to the kitchen, the kitchen makes the food, and the waiter brings it back to your table.

In web development:

  • You (The Customer): Are the external HTML website.
  • The Kitchen: Is Liferay (holding all the data and content).
  • The Waiter: Is the API. It carries your request for data to Liferay, and brings the data back to your website.

Liferay comes pre-packaged with hundreds of these "waiters" ready to take your orders. They are called Headless APIs.


Step 1: Preparing Liferay for Outside Visitors (CORS)

By default, Liferay is highly secure. If a random website tries to ask Liferay for data, Liferay acts like a bouncer at a club and blocks the request. We need to tell Liferay that it is okay to share data with our local computer while we build this project.

This security feature is called CORS (Cross-Origin Resource Sharing). Here is how to configure it:

  1. Log into your Liferay instance as an Administrator.
  2. Click the Global Menu (top right) and go to Control PanelSystem Settings.
  3. Under the "Security Tools" section, click on CORS.
  4. Click the Add button to create a new configuration.
  5. In the URL Pattern box, type: /o/* (This tells Liferay to apply this rule to all APIs).
  6. In the Allowed Origins box, type: * (Note: In a real business scenario, you would type your exact website address here, but the asterisk is perfect for learning and testing).
  7. Click Save.

Your Liferay "bouncer" will now let your HTML page through the door!


Step 2: Building the HTML Structure

Now, let's create our external website. Create a brand new folder on your computer, and inside it, create a file called index.html. Open this file in your favorite text editor (like Notepad, VS Code, or Sublime Text).

We are going to create a very simple page with a button. When we click the button, we want a list of blogs to appear.

Here is the HTML code to get us started:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Liferay App</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 40px; background: #f4f4f9; }
        .blog-card { background: white; padding: 20px; margin-bottom: 15px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
        button { padding: 10px 20px; background: #0B5FFF; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; }
        button:hover { background: #0044cc; }
    </style>
</head>
<body>

    <h1>Latest Company News</h1>
    <button id="fetchDataBtn">Load Articles from Liferay</button>
    
    <!-- This empty div is where we will inject the Liferay data -->
    <div id="blogContainer" style="margin-top: 20px;"></div>

</body>
</html>

This is standard HTML with a little bit of CSS to make it look pretty. Notice the empty <div id="blogContainer">. This is our blank canvas.


Step 3: Writing the JavaScript (The Magic)

Now for the fun part. We need to write a script that acts as the "waiter," asking Liferay for the blog posts. We will use the modern JavaScript fetch() function.

Add the following code right above the closing </body> tag in your HTML file.

<script>
    // 1. Set up our Liferay details
    const liferayUrl = "http://localhost:8080"; 
    const siteId = "20121"; // Replace this with your actual Liferay Site ID
    
    // We use Basic Authentication for testing (Email:Password)
    const username = "test@liferay.com";
    const password = "test";
    const credentials = btoa(username + ":" + password); // Encodes it to Base64

    // 2. Select our HTML elements
    const button = document.getElementById("fetchDataBtn");
    const container = document.getElementById("blogContainer");

    // 3. Create the function to get the data
    async function getLiferayBlogs() {
        container.innerHTML = "Loading data from Liferay...";

        try {
            // This is where we "call the waiter" (API Request)
            const response = await fetch(liferayUrl + "/o/headless-delivery/v1.0/sites/" + siteId + "/blog-postings", {
                method: "GET",
                headers: {
                    "Authorization": "Basic " + credentials,
                    "Accept": "application/json"
                }
            });

            // If the bouncer blocks us, or the page is gone, throw an error
            if (!response.ok) {
                throw new Error("Whoops! Liferay returned an error: " + response.status);
            }

            // Convert the Liferay data into readable JSON format
            const data = await response.json();
            
            // Send the data to our display function
            displayBlogs(data.items);

        } catch (error) {
            container.innerHTML = "<p style='color:red;'>" + error.message + "</p>";
        }
    }

    // 4. Create a function to display the data on the screen
    function displayBlogs(blogArray) {
        // Clear the "loading" message
        container.innerHTML = "";

        // Loop through every blog Liferay sent us
        blogArray.forEach(blog => {
            // Create a new visual card for each blog
            const blogHTML = `
                <div class="blog-card">
                    <h2>${blog.headline}</h2>
                    <p>${blog.articleBody}</p>
                    <small>Written by: <strong>${blog.creator.name}</strong></small>
                </div>
            `;
            // Add it to our empty container
            container.innerHTML += blogHTML;
        });
    }

    // 5. Tell the button to run our function when clicked
    button.addEventListener("click", getLiferayBlogs);

</script>

How this code works in plain English:

  • Lines 2-8: We define the address to our Liferay server, our Site ID, and our login credentials so Liferay knows we are allowed to see the data.
  • Lines 16-27: The fetch() command travels to the Liferay server and politely asks for the blog posts. We use await to tell the browser to wait patiently until Liferay responds.
  • Lines 40-55: Once Liferay hands us the data (in a format called JSON), we loop through every single blog post. For each one, we dynamically create a block of HTML containing the Headline, the Body, and the Author's Name, and we inject it into our page!

Step 4: Run Your Code!

Make sure your Liferay server is running in the background. Then, simply double-click your index.html file to open it in Google Chrome or Firefox.

Click the blue "Load Articles from Liferay" button. Within a fraction of a second, the page will communicate with Liferay and magically populate your screen with the latest blog posts!





💡 Pro Tips for Future Developers

As you get more comfortable with this, keep these advanced tips in mind:

  • Finding Your Site ID: If you don't know what your Site ID is, log into Liferay, go to your Site, click Site Builder → Pages, click the gear icon (Configuration) for the site, and you will see the Site ID listed at the top.
  • Security Warning: In our tutorial, we hard-coded our email and password into the JavaScript. This is fine for learning on your local computer, but never do this on a live public website! In the real world, you would use a secure method called OAuth 2.0 to get a temporary token instead.
  • Fetch Anything: You aren't limited to blogs! By simply changing the URL in the fetch() command, you can request Users, Documents, Categories, or Web Content Articles.

⚠️ Common Errors & Fixes

Programming is all about trial and error. If it doesn't work on the first try, don't panic! Check these common issues:

1. "CORS policy blocked the request"

If you see a red CORS error in your browser's developer console (F12), it means you skipped Step 1 of this guide. Liferay is blocking you. Go back and ensure you set up the CORS configuration in the Liferay Control Panel.

2. "Error: 401 Unauthorized"

This means your login credentials are wrong. Make sure the email and password in your JavaScript code match an Administrator account on your Liferay server.

3. "Error: 404 Not Found"

A 404 error means the API route doesn't exist. This usually happens if you type the siteId incorrectly. Double-check that your Site ID matches the one inside Liferay.


Conclusion

Congratulations! You have just successfully decoupled Liferay. By separating the data (Liferay) from the visual display (your HTML page), you have taken your first major step into the world of Headless Architecture.

Using this exact same method, you could build a mobile app, a smartwatch app, or a React dashboard that all pull their information from your central Liferay system.

What kind of data are you hoping to pull out of Liferay? Let me know in the comments below, and I might write a specific tutorial for it!


Frequently Asked Questions

1. Do I need to install Node.js or React to use Liferay APIs?

No! As you saw in this tutorial, you can connect to Liferay APIs using nothing but a plain text file, basic HTML, and the standard JavaScript built directly into every web browser.

2. Can I use this method to send data BACK to Liferay?

Yes. In this tutorial, we used a "GET" request to read data. If you want to create a new blog post from your HTML page, you would change the method to "POST" and send the text data in the body of the request.

3. What is JSON?

JSON stands for JavaScript Object Notation. It is simply a lightweight, organized text format that computers use to talk to each other. When Liferay sends us the blogs, it sends them as JSON, which makes it very easy for our JavaScript to read.

4. Does this work on older versions of Liferay?

The specific "Headless Delivery" APIs used in this tutorial were introduced in Liferay DXP 7.1 and perfected in 7.2, 7.3, and 7.4. If you are using Liferay 7.0 or older (like 6.2), you will have to use the older JSON Web Services (/api/jsonws).

5. Can I fetch images using the API?

Yes. The API will return the URL path to the image (e.g., /documents/portlet_file_entry/...). You can take that path, add your http://localhost:8080 to the front of it, and put it inside an HTML <img src="..."> tag to display it on your site.

Comments

Popular posts from this blog

service builder with crud operation in liferay

   Crud and Search opration in Liferay:      ->  Liferay use service builder techniq for Crud opration.    ->  Service builder purform by  Service.xml file.    ->  Service.xml file create table in database and also create class and diffrent method.   1)      Create service.xml file.             ->Create service.xml file in WEB-INF and write below code.             ->CODE:        < service-builder package-path = "com.test" >         < namespace > qr </ namespace >           < entity name = "Searchclass" local-service = "true"                     ...

How to create new site programmaticly in liferay with validation

Create site in liferay <%@page import="javax.portlet.PortletPreferences"%> <%@page import="com.liferay.portal.kernel.util.ParamUtil"%> <%@page import="com.liferay.portal.kernel.util.HtmlUtil"%> <%@page import="com.liferay.portal.kernel.util.StringPool"%> <%@page import="com.liferay.portal.kernel.util.UnicodeProperties"%> <%@page import="com.liferay.portal.service.LayoutSetPrototypeServiceUtil"%> <%@page import="com.liferay.portal.model.LayoutSetPrototype"%> <%@page import="com.liferay.portal.service.GroupLocalServiceUtil"%> <%@page import="java.util.List"%> <%@page import="com.liferay.portal.kernel.bean.BeanParamUtil"%> <%@page import="com.liferay.portal.theme.ThemeDisplay"%> <%@page import="com.liferay.portal.model.Group"%> <%@page import="com.liferay.portal.kernel.util.WebK...

Crud Operation in Vaddin Portlet

Crud Operation on Vaadin portlet Lets connect vaadin portlet with mysql database : put poretal-ext.properties file under class file with following code jdbc.default.driverClassName=com.mysql.jdbc.Driver jdbc.default.url=jdbc:mysql://localhost:3306/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false jdbc.default.username=root jdbc.default.password=root // this code will write under public class DemoVaadinApplication extends Application { String dbUrl = "jdbc:mysql:///lportal" ; String dbClass = "com.mysql.jdbc.Driver" ; Connection con = DriverManager. getConnection ( dbUrl , "root" , "root" ); How to insert data into mysql database table Here are complete code for inserting data into vadin table public class DemoVaadinApplication extends Application { String dbtime ; String dbUrl = "jdbc:mysql:///lportal" ; String dbClass = "com.mysql....