Integrating Clarity's Application with Fragments

Liferay provides a method to merge the power of page fragments with your custom elements, turning standalone applications into modular, configurable page elements. Clarity wants to enable their content creator team to highlight promoted distributor stores. To achieve this, they want to make the distributor locator app’s components configurable through the UI.

In these exercises, you’ll wrap the Distributor Map custom element into a fragment and add configurations to pass data from the page editor to the component.

Exercise: Preparing Clarity’s Custom Element to Use Fragment Configurations

Clarity’s planned fragment contains configuration fields for the Distributor Map custom element. They want to prepare their application to receive and handle this data. Here, you’ll modify the Distributor Map custom element to use fragment configurations.

  1. In your file explorer, go to the clarity-distributor-map-custom-element/src/components/ folder and open the Map.jsx file.
  2. For the Map constant, add a { promoStore } parameter within the parentheses.

    The promoStore parameter represents the fragment’s configuration field for promoting a distributor store on the map.

  3. Scroll down to the return block and find the <Marker> element.
  4. Below the position attribute, add this:

    icon={
        location?.name === promoStore ? new L.Icon({
            iconUrl: "https://maps.gstatic.com/mapfiles/ms2/micons/blue-dot.png",
            iconSize: [32, 32],
            iconAnchor: [16, 32],
        }) : new L.Icon({
            iconUrl: "https://maps.gstatic.com/mapfiles/ms2/micons/red-dot.png",
            iconSize: [32, 32],
            iconAnchor: [16, 32],
        })
    }	

    This checks the name of the specified promoted store against each distributor’s name. If the store name matches, the marker’s color changes to blue. If not, it remains red.

  5. Save the file.Now that you’ve updated the component to handle the fragment’s configuration field, you can edit the App.jsx file to pass the data to it.
  6. From the parent src/ folder, open the App.jsx file.
  7. For the App function, add a props parameter within the parentheses.

    This parameter saves data from the component’s attributes in an object structure.

  8. Within the function, add this:

    const promoStoreValue = props.promoStore;
    

    This constant stores the value of the promoStore attribute within the props object.

  9. Scroll down to the return block.
  10. For the <Map /> component, add this attribute within the tags:

    promoStore={promoStoreValue}	

    This passes the promoStore value from the parent App component to the child Map component.

  11. Save the file. Now, you can add the promoStore attribute to the App component within the main.jsx file.
  12. From the parent src/ folder, open the main.jsx file.
  13. For the <App /> component, add this attribute within the tag:

    promoStore={this.getAttribute('promoStore')}	

    This attribute stores and passes the root element’s promoStore value into the App component.

  14. Add the following import to main.jsx below the existing import section:

    import leafletCssText from 'leaflet/dist/leaflet.css?inline';	

    This changes the way you embed the CSS.

  15. Within the connectedCallback function, replace everything above the <StrictMode> section with the content from the snippet below to update the styling:

      connectedCallback() {
          const style = document.createElement('style');
          style.textContent = leafletCssText;
          const mountPoint = document.createElement('div');
          this.appendChild(style);
          this.appendChild(mountPoint);
          this.root = createRoot(mountPoint);
          this.root.render(
              <StrictMode>
                  <App promoStore={this.getAttribute('promoStore')} />
              </StrictMode>
          );
      }	
  16. Go to the client-extensions/clarity-distributor-map-custom-element/ folder and open the client-extension.yaml file.
  17. Below the clarity-distributor-map-custom-element definition, add this:

    clarity-distributor-map-import-map:
        name: Clarity Distributor Map Import Map
        type: jsImportMapsEntry
        bareSpecifier: clarity-distributor-map-custom-element
        url: assets/*.js	

    This defines a new JS import map client extension to expose the custom element’s resources. Notice that the url attribute matches the custom element’s urls value to correctly retrieve the necessary resources.

  18. Save the file and deploy the client extension.

Great! You’ve updated the Distributor Map custom element to handle the fragment’s promoStore configuration. Next, you’ll create the fragment and configure that configuration option.

You’ve also made your custom element more versatile so that it can not only be used as a widget but also as a reusable component you can use in fragments and templates by using a JS import map client extension to import the custom element’s resources.

NOTE
The jsImportMapsEntry only bundles JavaScript, while customElement client extension types bundle both JavaScript and CSS. As a result when working with JS import maps, you’ll need to implement embedded inline CSS or leverage a globalCSS client extension.

Exercise: Creating the Custom Distributor Map Fragment

With Clarity’s Distributor Map custom element configured, they’re ready to use it as a page fragment. Here, you’ll create the Custom Distributor Map fragment and wrap the custom element within it.

  1. In your Liferay instance, open the Site Menu (Site Menu icon), expand Design, and click Fragments.
  2. Click the (+) to create a new Fragment Set named Clarity Distributors.
  3. Within the fragment set, create a new Basic Fragment called Custom Distributor Map.

    Within the fragment set, create a new Basic Fragment called Custom Distributor Map.

    Before adding the code, you’ll add configuration options to the fragment.

  4. Go to the Configuration tab.
  5. Within the JSON window, replace the current content with this:

    {
        "fieldSets": [
            {
                "fields": [
                    {
                        "dataType": "string",
                        "defaultValue": "",
                        "label": "Promoted Store",
                        "name": "promoStore",
                        "description": "Name of the store that is promoted on the map",
                        "type": "text",
                        "typeOptions": {
                            "placeholder": "Enter the full name of the store"
                        }
                    }
                ],
                "label": "Promotions"
            }
        ]
    }	

    This creates a new Promotions configuration set and an editable Promoted Store option. You can now reference this option in the fragment’s code.

    NOTE
    Notice that the configuration can have a default value using the defaultValue field. You can define this value directly within the JSON or the custom element’s client-extension.yaml file.
  6. Go to the Code tab and add this code within the HTML window:

    <div class="fragment_clarity_map">
      <clarity-distributor-map-custom-element 
        promoStore="${configuration.promoStore}"></clarity-distributor-map-custom-element>
    </div>

    This creates a div element that wraps the Distributor Map custom element, which retrieves the promoStore field’s value. However, the fragment doesn’t render anything because it doesn’t include the custom element’s source.

    To fix this, import the custom element using the previously defined JS Import Map directly in the fragment’s JavaScript window.

    import 'clarity-distributor-map-custom-element';	
    This makes the Distributor Map element available to the fragment. It should now display in the preview window.

    The preview should render once the Javascript and HTML snippets are imported.

  7. Click Publish.
  8. Navigate to the Distributor Details page and start editing the page.
  9. Replace the Clarity Distributor Map widget with the Custom Distributor Map fragment.
  10. Select the fragment.
    Notice there is a new Promotions setting in the configuration side panel.

    Select the fragment. Notice there is a new Promotions setting in the configuration side panel.

  11. For the Promoted Store field, enter Retro Eyewear.
  12. Click Publish to publish the page.
  13. Verify the map marker associated with Retro Eyewear is blue.

    Verify the map marker associated with Retro Eyewear is blue.

NOTE
By default, changes made to a custom fragment’s code are not propagated to deployed instances of the fragment. Whenever you make changes to a fragment, propagation is required to apply those updates to your deployed fragments.

Great! You’ve wrapped the Distributor Map custom element in a configurable fragment and included it in the Distributor Details page. This enables Clarity’s content creators to modify the application without changing the code.

Conclusion

Wrapping custom elements within fragments empowers you to turn applications into modular, configurable page elements. This enables non-technical teams to tailor custom elements and deliver content-rich, dynamic digital experiences without touching any code.

Next, you’ll learn how to leverage the Shadow DOM with Fragments in Liferay.

loading-knowledge-label