Lately, I was challenged with the requirement to show a page heading and some breadcrumbs on each page of a Community. The styling required some css classes.

While the initial thought was to use HTML Editor blocks to prevent code, and continue with clicks, this resulted in a significant overhead in the maintenance of aligning the headings. Business decided to change their minds on whether the heading should have trailing dots or not and even while we had about 15 pages, the clicks vs. code benefits felt less correct.

The Community pages already showed a Custom Theme Layout and the thought of ‘simply’ showing the title on each page, and centralising the complete logic on styling and heading syntax sounded like a nice idea…

How to derive the SEO Page Title

Salesforce Communities retrieve the page title asynchronously and therefore one cannot simply display document.title. Adding some delay (setTimeout) before fetching reeks to code-smell and is tricky due to the fluctuating time required to load, as well as you don’t want to impact the customer experience too much. Observing mutations (MutationObservers) to the document.title tag is unfortunately ruled out in Lightning, due to LockerService.

Solution between Winter and Spring ’21

Fortunately, there was some genius sharing the ability to add an Handler on the forceCommunity:routeChange event, which is triggered when the page’s URL is changed.

// Aura.cmp
<aura:handler event="forceCommunity:routeChange" action="{!c.setPageName}"/>

// AuraController.js
({
	setPageName: function( cmp, event, helper ){
        cmp.set( 'v.pageName', window.document.title );
    },
} )

This worked perfectly fine till Winter ’21 came. For some reason this introduced the URL to be changed once, but the title to be changed in two-steps, first to ‘Widget’ and after to the [SEO Page title]. Unfortunately for this implementation the routeChange fired too soon and customers would see Widget in Heading on each page.

It required a little investigation into the core scripts of Salesforce Communities (using the Chrome Developer Tools) to find the magic of seoAssistant.js. This script is part of the components-library in the Aura framework and responsible for (asynchronously) retrieving the title and tags for the displayed page. Happiness arose again, finding the title and tags are shared between components (to a.o. set it in the title tag) using the markup://siteforce:setSEOProperties event! Then it only required little change to retrieve the correct page title!

// Aura.cmp
<aura:handler event="markup://siteforce:setSEOProperties" action="{!c.setPageName}" />

// AuraController.js
({
	setPageName: function( cmp, event, helper ){
        let pageTitle = evt.getParam( 'title' ) || "";
        if( pageTitle && pageTitle != 'Widget' ){
            cmp.set( 'v.pageName', pageTitle );
        }
    },
} )

Update: solution per Spring ’21

Unfortunately, the quest continued after Spring ’21 reached out Salesforce orgs. While the Aura Theme Designs continued to work, one could not save and compile the component again while referring the setSEOProperties event (FIELD_INTEGRITY_EXCEPTION - No EVENT named setSEOProperties found). Apparently, the event was restricted by Salesforce, though it was still recognised (when referring setseoproperties (lowercase), the Exception would still show the correct casing).

Some trial and error later, showed the original suggestion was nearly sufficient to get back on track and showing the page title configured in the Community Builder SEO section.

Using a combination of handlers on both aura:locationChange and forceCommunity:routeChange events, allows to have a robust and solid coverage of retrieving the page title in time.

In my use-case this allowed to set the pageName in the Theme Layout, avoiding manual maintenance in the Community Builder. However, this can of course also be used to know when to trigger an Analytics script like Google Analytics (GA).

<!-- Page Attributes -->
<aura:attribute name="pageName" type="String" access="public" />
<!-- Handler -->
<aura:handler event="aura:locationChange" action="{!c.setPageTitle}"/> <!-- Page load -->
<aura:handler event="forceCommunity:routeChange" action="{!c.setPageDetails}"/> <!-- URL change -->

<!-- Page content -->
<div class="content">
  <div class="heading">
  	<a class="breadcrumb" onclick="{!c.goToBaseUrl}"><span></span> Back</a>
  	<h1>{!v.pageName}</h1>
  </div>
  {!v.body}
</div>
( {
  /**
   * On LocationChanged (first page load) or on RouteChanged (url change in Community)
   * Update pageName to show on page
   */
  setPageDetails: function( cmp, event, helper ){
    // Always update page name for consistency
    cmp.set( 'v.pageName', document.title );
  }
} )

Conclusion

The above code allows a developer to retrieve the page title of the displayed page which is set in SEO Section of the Community Page Builder, or to know when an Analytics tool should be informed the page was loaded. Allowing consistency across your Community, while still allowing Administrators / Content Moderators to maintain the headings which are shown to the customer.

When leveraging this code snippet, one should however be very aware this concerns an undocumented feature in Salesforce and should be used with care. Make sure to do regression tests after each Salesforce release and please reach out when something stops working as that might be relevant for me as well 😉

#HappyCoding !

How useful was this post?

Average rating 5 / 5. Vote count: 4

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

2 thoughts to “Display SEO Page Title in ThemeLayout

  • Gopalan

    Hi

    Have you come across a use case where we need to set dynamic SEO title for a flexi page dependent on a component

    Thanks
    Gopalan

    Reply
    • Reinier van den Assum

      @Gopolan, thanks for your comment! Unfortunately, I haven’t been in the scenario of specifying the window.title within a LWC which is loaded in a Flexipage. I would expect window.title will not be able to set it from within your LWC Controller, as you most likely tried that already. Just a out-of-the-box-thought is that within Salesforce Console, there are methods which allow to open a Tab or SubTab which has a parameter for the tab-title which you might be able to leverage (with a default reload in the LWC). However, I wouldn’t directly know whether it is even possible to change the FlexiPage on a standard Salesforce User (other than changing the record name or such), sorry. Maybe there is an Event running on the background that normally fires to update the title, which you could fire. Feel free to elaborate a bit on your use-case. Also, if you do come across the solution, I am more than eager to know as well!

      Reply

Leave a comment to Reinier van den Assum Cancel reply

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