Skip to content
Coding With The Force

Coding With The Force

Making Salesforce Development a Breeze

  • Salesforce Apex Master Class
    • Apex Programming Language Basics
  • Salesforce Administration
    • Salesforce Administration: Single Sign-On
    • Salesforce Administration: Custom Settings
    • Salesforce Administration: Process Builders
  • Salesforce Development Tutorials
    • Salesforce Development: Apex Triggers
    • Salesforce Development: IDE Setups
    • Salesforce Development: Lightning Web Components (LWC)
    • Salesforce Development: Apex
    • SoC and the Apex Common Library Tutorial Series
  • About Us

Tag: External Links

Posted on September 20, 2020January 20, 2021

Salesforce Development (LWC) : Creating a configurable Lightning Web Component using Custom Metadata

Tweet

What is Custom Metadata and why would we create a configurable Lightning Web Component?

Custom Metadata is a wonderful thing. You set it up much like a custom object, but you use it for an entirely different purpose. Typically you use custom metadata much like you would utilize a config file in many other development languages. The nice part is, unlike a config file in normal coding languages where you have to write a bunch of XML, Salesforce does all that for you automatically. This custom metadata can be leveraged in your code to allow it to be dynamic and configurable. By utilizing it instead of hardcoding values into your code, you no longer need a developer to update code, but instead could have an admin update a few values in your custom metadata object. Noice!

As far as why we should strive to make our Lightning Web Components configurable instead of hardcoding values, it benefits us in the following ways:

1) Developers don’t have to waste time on simple updates, changing a label in the component or things like changing the default amount of rows shown in a table, can just be updated in the Custom Metadata files by an admin.

2) Updates take seconds instead of hours.

3) Removes the need to deploy components for small cosmetic updates.

There’s probably plenty more, but trust me… if you’re a developer who is tired of making boring garbage updates to your web apps, it’s time to start leveraging custom metadata types.


Configurable App Example: The LWC External Links Utility Bar App (My Open Source External Link App)

One of the most common things I’m asked to do with new Salesforce implementations is create a way for users to link out to other external applications within Salesforce. The first time I made this I hard-coded everything and when I ran into the exact same situation on my next client I decided I just need to make this configurable so I can drop it into any clients org with as little code as possible. I’m glad I made that choice because my next four clients asked for the exact same thing!

Thanks to custom metadata I’m able to dynamically do a lot of things without having to write hardly any code. The app can do the following with zero updates to the code:

1) Change the ordering of links
2) Determine whether to open the link in a browser tab or a Salesforce console tab
3) Determine whether the link should be added or removed from the link list
4) Change the URL for the link
5) Change the label for the link

Pretty toight am I roight?

So let’s get into the code and the custom metadata setup.


How to setup Custom Metadata Types

Setting up a custom metadata type is super easy to do. In Salesforce go to Setup -> Custom Metadata Types and then click the “New Custom Metadata Type” button once there. You’ll find setting up a custom metadata type very closely resembles setting up a custom object. Now as much as I appreciate everyone that reads this blog, I’m not gonna go into detail on how to set one one up. Primarily because Salesforce already has a particularly good trailhead for it. You can check it out here. If you watch the video linked above I also go into some brief detail as to how to do it.


Leveraging the Custom Metadata in your code

So how do we leverage this custom metadata in our code? Pretty simple. We query for its data in our Apex controllers just like we would for a custom object. In my custom external links component the apex code is this simple (you can also find this code and the custom metadata for it in this Github repository):

public with sharing class External_Links_Controller
{
	@AuraEnabled
	public static List<Utility_Bar_Link__mdt> getUtilityBarLinks()
	{
		return [SELECT MasterLabel, gAuto__Link_URL__c, gAuto__Open_in_console_tab__c, 
                gAuto__Order__c FROM gAuto__Utility_Bar_Link__mdt WHERE gAuto__Active_Link__c 
                = TRUE ORDER BY gAuto__Order__c ASC];
	}
}

As you can see, we just query for the utility bar link custom metadata and return it to our LWC, but how exactly do we use it in our LWC?? Let’s check out the code for it as well.

<!--The HTML LWC Template -->
<template>
        <!--Iterating through our list of external links and creating an input of type button 
            with data attributes that hold our important link information -->
	<template if:true={linkList}>
		<template for:each={linkList} for:item="link">
			<input key={link.Id} data-id={link.Id} class="slds-button slds- 
                         button_neutral linkButton" value={link.MasterLabel}
	                 data-url={link.gAuto__Link_URL__c} data-opentab= 
                         {link.gAuto__Open_in_console_tab__c} type="button" onclick= 
                         {openLink}/>
		</template>
	</template>
</template>
/*The LWC Javascript Controller*/
import {LightningElement} from 'lwc';

//Importing our apex class method
import getUrlLinks from '@salesforce/apex/External_Links_Controller.getUtilityBarLinks';

//Importing the navigation mixin module so that we can navigate to new browser or console tabs
import {NavigationMixin} from 'lightning/navigation';

//Make sure to extend NavigationMixin here so that we can use it in the code
export default class ExternalLinksComponent extends NavigationMixin(LightningElement)
{
	linkList;
        
        //This method is rendered on the load of the component. I use it instead of @wire
        //because @wire has a bug that sometimes causes Aura components in the same page
        //to not be able to do DML transactions
	connectedCallback()
	{
                //Calling our controller method to get our links and then assigning them to 
                //our linkList variable in the LWC controller
		getUrlLinks().then(
			result =>
			{
				this.linkList = result;
			}
		).catch( error =>
		{
			console.error('This is the error ::: ' + error);
		});
	}

        //This method is called when one of the link buttons is clicked. It determines whether 
        //to open this link in a console tab or a browser tab
	openLink(event)
	{
                //Getting the url for our link from the data-url attribute on the input button 
                //we clicked
		let urlToPass = event.target.getAttribute("data-url");

                //If the data-opentab attribute is true, we need to dispatch a custom event 
                //for our housing Aura component to handle 
		if(event.target.getAttribute("data-opentab") === "true")
		{
			const openTabEvent = new CustomEvent('opennewsubtab', {
					detail: {urlToPass}
			});

			this.dispatchEvent(openTabEvent);
		}
                //Otherwise we need to open the url as a browser tab
		else
		{
                        //The standard__webPage NavigationMixin type allows us to open this in
                        //a new browser tab.
			this[NavigationMixin.Navigate]({
				type: 'standard__webPage',
				attributes:{
					url: urlToPass
				}
			});
		}
	}
}
/**
 * LWC CSS
 */
.linkStyles
{
    display: block;
    text-align: center;
}

input:hover
{
    color: rgba(27, 82, 151, 1);
    text-decoration: none;
}

input:visited
{
    text-decoration: none;
    color: rgba(27, 82, 151, 1);
}

.linkButton
{
    width: 100%;
    height: 30px;
}
<!--
 - Aura Component code. This is needed because LWC's do not currently have the ability to open Salesforce console tabs.
 -->

<aura:component implements="force:appHostable, flexipage:availableForAllPageTypes, lightning:isUrlAddressable" access="global" description="External_Links_Wrapper">

	<lightning:workspaceAPI aura:id="workspace"/>

        <!--Adding our LWC and handling our custom event we declared in it (opennewsubtab)-->
	<c:external_links_component onopennewsubtab="{!c.openConsoleTab}"/>

</aura:component>
/*Aura component javascript controller*/
({
        //This function is utilized to open a new console tab within your console apps
	openConsoleTab : function(component, event, helper)
	{
                //This finds the workspace for our current console app
		let workspace = component.find("workspace");

                //This opens the url as a tab in the console and auto focuses on that tab 
		workspace.openTab(
			{
				url: event.getParam("urlToPass"),
				focus:true
			}
		);
	}
});

So as you can see from the code above, the custom metadata determines basically every action that the LWC takes. Nothing is hard-coded for the most part, the actions are all determined by the custom metadata and the list of links comes directly from it as well.

There are two important things to note about this particular code that is unrelated to the concept of custom metadata.

1) An Aura component is included because LWC’s cannot current open console subtabs, so that must be handled in Aura.

2) Links can only be opened in a console tab if you can alter the websites Content Security Policy (CSP) to allow Salesforce to iFrame in your site. If you didn’t know, all data inside console tabs is iFrame’d in, there is no way to alter this behavior currently.

If you want more extremely detailed information on how this code actually works, please refer to the YouTube tutorial above. I go very in depth with the code, how the custom event passing works, etc.


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Share this:

  • Twitter
  • Facebook
  • LinkedIn
  • Reddit
  • Print
Proudly powered by WordPress