5

Here's the situation as I understand it of what we want to do:

An lwc component is created that uses custom metadata to set the data inside the component. One of those things is a field with a value type of string with the name of a custom label (a label instead of string for internationalization/translation purposes). In the lwc component, we use that string value to then form the import call for the label so we have access to the data.

As I understand it, the way to import a custom label in LWC is at the top as an import, like so:

@import someLabel from '@salesforce/label/c.myLabelsName';

However, what we don't know what the label is called until we pull in the meta data text. In aura this would be done something like this:

$A.getReference("$Label.c." + response.getReturnValue()[0].Tiles_Component__r.MasterLabel);

From what I've been able to google and poke around here, I'm not seeing a solution, but wanted to make sure I'm not missing something. Is there any way to do like aura can in LWC? And if not, this functionality is coming eventually correct?

2 Answers 2

9

New and Improved Access

We no longer need the Visualforce page, as we can now Access Labels in Apex Dynamically.

@AuraEnabled(cacheable=true)
public static String getLabel(String namespace, String label, String language) {
  return Label.get(namespace, label, language);
}

Or multiple labels:

@AuraEnabled public Map<String, String> getLabels(String namespace, String[] labels, String language) {
  Map<String, String> results = new Map<String, String>();
  for(String label: labels) {
    results.put(label, Label.get(namespace, label, language);
  }
  return results;
}

Original Answer

The point of non-dynamic labels is to provide compile-time safety of labels, and prevent deletion/renaming of labels that would otherwise break code. As such, there's no real support for dynamic labels in LWC. There's no known timeline when, or if, this might become available.

One possible solution is to write a Visualforce page that accepts a parameter and returns the label. I came up with this idea independently while answering this question, but someone's already done the work, but I made it better, so here goes:

label.page

<apex:page sidebar="false"
           showChat="false" 
           showHeader="false" 
           applyBodyTag="false" 
           applyHtmlTag="false"
           contentType="application/json"
           language="{!$CurrentPage.parameters.lang}">{
    "value": "{!JSENCODE($Label[$CurrentPage.Parameters.label])}"
}</apex:page>

To use this, call it from a controller:

@AuraEnabled public Map<String, Object> getLabel(String lang, String label) {
  PageReference ref = Page.getLabel;
  ref.getParameters().putAll(
    new Map<String, String> {
      'lang' => lang,
      'label' => label
  });
  return (Map<String, Object>)JSON.deserializeUntyped(ref.getContent().toString());
}

At this point, you can import the method, wire it up, however you'd like to use it, and you'll get your dynamic labels, just like you'd expect. However, keep in mind that you now need round-trip server calls, so use this sparingly.

9
  • Cool trick.. Wondering why limit to just 1 label? Did you try bulkify it by passing List<String> labels ? Commented Aug 21, 2020 at 0:00
  • 2
    @salesforce-sas Could you bulkify it, but it would need some tweaking, either a VF controller or changing the Apex to call the page repeatedly. But it is definitely possible.
    – sfdcfox
    Commented Aug 21, 2020 at 0:12
  • Gotcha -- wish there was a way to do this without a hack (our dev team is worried about a potential security issue using a visualforce page to do this work). Thanks for the solution and explanation
    – babyYoda
    Commented Aug 26, 2020 at 17:48
  • 1
    @RadekMichna No, that might be on me, actually. Thanks for bringing this up. Should definitely convert to a string first.
    – sfdcfox
    Commented Feb 10, 2022 at 15:51
  • 1
    @PhilW Here's the demo. Enjoy!
    – sfdcfox
    Commented Feb 14, 2022 at 20:26
8

As of Summer '23, the Apex language now allows you to dynamically get a label WITHOUT using the visualforce trick above.

There is a new method, system.label.get() which takes a label name (and optionally a namespace and language) and returns that label.

This should make localizing LWC and anything else easier.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .