Displaying web content in a React Widget

Check out how to list multiple web contents within your React Widget using Liferay's Headless APIs!

Liferay Development
Article

Liferay is a tool that natively provides several ready-to-use functionalities. Some of them include content management, user management, categorization system, among others.

If you've been a Liferay developer for a while, you've probably implemented some backend code to interact with these functionalities using source code APIs, such as JournalArticleLocalService or UserLocalService.

However, in recent years, the focus has increasingly been on removing backend responsibility, either through no-code/low-code tools or through Rest APIs that facilitate access to platform resources.

Today we will see how to use these native Rest APIs to display web content within our React Widget, created in this post.

Headless APIs

In older versions of Liferay, it was common to use Rest APIs generated by remote services of Service Builders when we needed to implement more complex logic on the frontend.

These APIs are made available at the /api/jsonws endpoint and are usually somewhat difficult to use. They generally have many input parameters and often produce errors.

That's where Headless APIs come in. They are endpoints that provide access to portal resources, however, following Rest standards, integration happens more simply and directly.

You can find all these endpoints under the path /o/api, along with documentation of the fields to be sent and what to expect in response. Note that you need to be logged in to access these endpoints.

 

 

The endpoints are divided into various groups under the REST Applications select. For today's post, we will use an endpoint in the headless-delivery/v1.0 group.

 

 

Search for Structured Content and open the first endpoint in the section

 

 

In Headless, StructuredContent is our Web Content (or Journal Article on the backend, and yes, Liferay loves to give several different names to the same entity). We will list all the content of our main site.

To get the site id, just go to your homepage, open the JavaScript console, and execute the command

themeDisplay.getScopeGroupId();

 

 

For Liferay, Group is the same as Site. Fill in the siteId input in Headless and click execute. If it returns a 403 error, simply reload the page and repeat the procedure. In the response section, the web contents of the site will appear.

 

 

Make sure there are created contents. If you don't know how to create content, take a look at this video from our channel: Entendendo TUDO sobre CONTEÚDO WEB!.

In the section above the response, we can see the curl command of the request

 

 

Notice that the request is relatively simple to make and the response is a JSON with all relevant data of the web contents. Now just integrate our React Widget with this endpoint.

Calling endpoint by React Widget

We will use the native fetch command to make AJAX calls. In the same directory as the index.js file, create the api.js file with the following code


async function fetchWebContents() {
  return (
    await fetch(
      `/o/headless-delivery/v1.0/sites/${themeDisplay.getScopeGroupId()}/structured-contents`,
      {
        headers: {
          accept: "application/json",
          "x-csrf-token": Liferay.authToken,
        },
      }
    )
  ).json();
}

export default {
  fetchWebContents,
};

In the AppComponent.js file, paste the following code


import React, { useEffect, useState } from "react";
import api from "./api";

export default function AppComponent() {
  const [webContents, setWebContents] = useState([]);

  useEffect(() => {
    api.fetchWebContents().then((response) => setWebContents(response.items));
  }, []);

  return (
    <>
      {webContents.map((webContent) => (
        <div key={webContent.id} className="container">
          <h2>{webContent.title}</h2>
          <p>{webContent.description}</p>
          <div className="infos">
            <span>{webContent.creator.name}</span>|
            <span>{webContent.dateCreated}</span>
          </div>
        </div>
      ))}
    </>
  );
}

Here we make the call to the Headless API inside a useEffect and store the response results in a state of the functional component. The visual part of the component consists only of listing these contents.

To improve the presentation of the component, copy this code into the style.scss file inside the css folder


.container {
	display: flex;
	flex-direction: column;
	border-radius: 15px;
	padding: 25px;
	align-items: flex-start;
}

.infos {
	span {
		color: #6b6c7e;
		margin: 0 20px;

		&:first-child {
			margin-left: 0;
		}
	
		&:last-child {
			margin-right: 0;
		}
	}
}

Now, when you reload the page, you should see a list of web contents

 

 

Inspecting the network, we can see the request to the Headless

 

 

And the response

 

 

With this, you can integrate your React application with various native functionalities of your portal, just by consulting the Headless endpoints.

That's it for this post, until next time!


Stay Ahead with Our Liferay Newsletter

Subscribe now to get the latest news, technical tips, exclusive Simplify content, trends, events, and more about the global Liferay ecosystem directly in your inbox.

Latest contents

For real, what is Liferay DXP?

16/08/2024

Liferay Development
Digital Transformation
Article

If you've ever tried to understand Liferay and ended up more confused, you're in the right place. Let’s simplify it.

Learn more
Enhancing Digital Customer Experience: Personalization and Integration with a Digital Experience Platform

13/05/2024

Digital Transformation
Article

How a Digital Experience Platform (DXP) Satisfies Evolving Consumer Expectations: The Need for Customized, Integrated, and Omnichannel Solutions

Learn more
Displaying web content in a React Widget

19/03/2024

Liferay Development
Article

Check out how to list multiple web contents within your React Widget using Liferay's Headless APIs!

Learn more