+ Start a Discussion
LaurentDelcambreLaurentDelcambre 

LWC: how to get translated value from Label dynamically

Hi,

We used to be able to do this in Aura:
String labelName = 'mylabel';
$A.getReference("$Label.c."+ labelName);



$A is not accessible in LWC

Following the documentation I can only see a way to get access to Label's value through import.
As far as I know import don't work dynamically. You can only write an import if you know the name of the label.

I was hoping for a solution involving Apex and/or SOQL but could not find anything.

Any idea?
 
Raj VakatiRaj Vakati
You have to use like below below   

https://rajvakati.com/2019/02/10/using-custom-labels-in-lightning-web-components/
https://www.salesforcecodecrack.com/2019/01/how-to-access-custom-labels-in.html
https://developer.salesforce.com/docs/component-library/documentation/lwc/create_labels.html
import { LightningElement } from 'lwc';
import edit from '@salesforce/label/c.Edit';
import save from '@salesforce/label/c.Save';
import title from '@salesforce/label/c.Title';
 
export default class Labelexamples extends LightningElement {
     label = {
         edit,
         title,
         save
     };
}

 
LaurentDelcambreLaurentDelcambre
Thanks for the answer but you are missing the point.


The name of the label would be stored in a String. We can't concatenate strings in import so that would not work.

In the question the emphasis is on "dynamically".
 
Raj VakatiRaj Vakati
I dnt think so we do have any options with the current LWC release for Dynamic Lable ..Did you find any other options ?
Rushikesh KhandaleRushikesh Khandale
Hi, 
To dynamically get the custom label in LWC you can use Apex as a workaround.
Import the apex function :
import findLabel from '@salesforce/apex/FindTranslatedLabel.findLabel';
Wire the imported function :
@wire(findLabel, { searchKey: 'myLabel' })
    labelName;

The Apex method takes a string parameter called searchKey, and returns the custom label for that parameter:
public with sharing class FindTranslatedLabel {
    @AuraEnabled(cacheable=true)
    public static String findLabel(String searchKey) {
        String customLabelValue = System.Label.searchKey;
		return customLabelValue;
    }
}
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex
Hope this helps you
If this helps kindly mark it as solved so that it may help others in future.

Thanks and Regards
 
Phil WPhil W
I looked at the above solution from Rushikesh Khandale and thought it looked suspiciously easy given that I previously looked for a way to dynamically access labels from Apex and could find none (the workaround was to actually dynamically instantiate a visualforce component from the apex that references the required label). I therefore tried it out using anonymous Apex and found that, while "System.label.searchKey" would "compile", this did not return the correct label.

The solution is to add this to one of your Apex classes and to call it with the label name as a string:
 
public static String getLabelString(String labelName) {
    Component.Apex.OutputText output = new Component.Apex.OutputText();

    output.expressions.value = '{!$Label.' + labelName + '}';

    return String.valueOf(output.value);
}

 
Niels KeuningNiels Keuning
Phil, can you explain a little bit more how that method would work together with an LWC? Do you maybe have example code for the LWC with the call to that method?

The situation I'm having is as follows:
I have an LWC with a table that shows data, which is coming from an external system (http endpoint). The data we receive contains codes that we need to translate to a custom label in Salesforce, because we don't want to show codes to our users. I've made an Apex method that returns a list/json array where the codes are translated to the correct custom label names.
But when putting that data in the table in LWC, I want the custom label value to be shown. I think your solution could help me with that, but I'm not completely sure how exactly.
Phil WPhil W
Hi Niels,

If you want this to be accessible from LWC, just annotate it with @AuraEnabled. If you want to use it via a wire it would also have to be cacheable, but if you call it imperatively (which I suspect is what you'd want to do) you don't need it to be cacheable - that said making it cacheable makes sense since labels don't tend to change much.

In your Apex class, let's call it Labels:
 
/**
 * Provides dynamic access to labels.
 */
public class Labels {
    /**
     * Returns the value of the label requested by name, in the current user's locale.
     *
     * @param labelName must name a custom label for which the value is required. Not null
     *
     * @return the value of the requested label in the current user's locale. Will not be null
     */
    @AuraEnabled(Cacheable = true)
    public static String getLabelString(String labelName) {
        Component.Apex.OutputText output = new Component.Apex.OutputText();

        output.expressions.value = '{!$Label.'  + labelName + '}';

        return String.valueOf(output.value);
    }
}

The LWC can then use the Labels.getLabelString function imperatively in this way:
 
import {LightningElement} from 'lwc';
import getLabelString from '@salesforce/apex/Labels.getLabelString';

export default class SomeComponent extends LightningElement {
    ...

    someFunction() {
        getLabelString({labelName: "SomeLabelName"}).then(text => {
            // the "text" value is the label string for "SomeLabelName"
            // use it however you need. Clearly you can replace "SomeLabelName" with a
            // variable reference or whatever to make this truly dynamic label access
        }).catch(error => {
            // the "error" is whatever went wrong. Not sure if this is called if the label name
            // doesn't select an existing label - I would hope so but this needs testing
        });
    }
}

Hopefully that gives you enough to work with.
Niels KeuningNiels Keuning
Hi Phil,

Thank you for your quick response!

If I try that, it compiles fine, but when I try to call the method I get an error:
System.VisualforceException: Visualforce Component types can only be created within a controller class for a Visualforce page.

I've found another example where someone mentioned a similar solution (https://success.salesforce.com/answers?id=90630000000hIRaAAM), but also a comment from someone there:
The answer above for accessing labels dynamically does not work any longer.  Salesforce returns an error stating that it must be used in a VF Controller.

So sadly enough I don't think we can use that anymore..

I've also tried the solution Rushikesh Khandale mentions above, but that also doesn't work for me. Can't get 'searchKey' to be dynamic, it always expects the exact custom label name already.

I prefer to use LWC, much easier to work with compared to VF or Aura in my opinion. But this seems to be one of those situations where you need to go back to VF or Aura.. Unless you, or anyone else, has any other ideas :)
Phil WPhil W
Perhaps a workaround would be to downgrade the API version on the "Labels" class to avoid where Salesforce introduced this limitation? Not sure what API version would work, if any. Give it a try. The API version is in the meta XML file for the class.
Niels KeuningNiels Keuning
If I look at other threads where a solution like that was offered, it seems it worked in Winter '17 (38) and/or Spring '17 (39).
Just tried with API versions going back to 28 (Summer '13), all return te same error: Visualforce Component types can only be created within a controller class for a Visualforce page.
Seems to have been blocked for all, ignoring the API versions. 

 
Phil WPhil W
Shame. Sorry, you'll have to figure out a different approach then :(
Niels KeuningNiels Keuning
I'll go to Aura for now I think, thank for your response anyway!
If I find a solution for this, I'll try to remember this thread and get back to it :)
Phil WPhil W
You could include an Aura component in the page that basically provides a service (via Lightning Message Service or using the "pubsub" approach) to convert a label name into the label text. You can then write your LWC components to send requests to the component, and listen out for responses from the component (again using the LMS or "pubsub" approach). Holding the labels in appropriate tracked properties would cause re-rendering once the label's value is received back from the "label service" component.

NB: This would be a fair amount of effort, but if you google around you can find details on both LWC "pubsub" and LMS.
Niels KeuningNiels Keuning
Ah, yes I've read about the Lightning Message Service in the release notes. Seemed interesting, but didn't had a good usecase to try it on. This seems like one I should try it for. 
Maybe a bit too much effort for something like this, but good to get some experience with it I guess. I'll give it a go, thanks for remembering me about it!
mukesh guptamukesh gupta
Hi Laurent,

Translate value automatically change according your org lenguage. so you need to mentioned in custom label with different lenguages

below in LWC code to get the custom label values :-
 
// labelExample.js
import { LightningElement } from 'lwc';

// Import the URL for the static resource named 'salesforceLogo'
import SALESFORCE_LOGO from '@salesforce/resourceUrl/salesforceLogo';

// Import custom labels
import greeting from '@salesforce/label/c.greeting';
import salesforceLogoDescription from '@salesforce/label/c.salesforceLogoDescription';

export default class LabelExample extends LightningElement {
    // Expose the static resource URL to use in the template.
    logoUrl = SALESFORCE_LOGO;

    // Expose the labels to use in the template.
    label = {
        greeting,
        salesforceLogoDescription,
    };
}
 
<!-- labelExample.html -->
<template>
    <c-page-header header="Using static resources and custom labels" description="This sample shows how to reference external items like static resources and custom labels"></c-page-header>

    <c-card>
        <img src={logoUrl} alt={label.salesforceLogoDescription} width=100><br>
        <br>
        {label.greeting}
    </c-card>
</template>

If this solution is usefull for you, Please mark as a Best Answer to help others.



Regards
Mukesh
Phil WPhil W
Murkesh, this doesn't even try to answer the original question.
Priyanka Lakhani 1Priyanka Lakhani 1
We need to create Visualforce page as a template to be read from Apex.
<apex:page showHeader="false" sidebar="false" controller="LabelTranslatorController" language="{!language}" standardStylesheets="false" contentType="application/json">
{!$Label[label]}
</apex:page>
 
public with sharing class LabelTranslatorController {
    public String language { get; set; }
    public String label { get; set; }
     
    public LabelTranslatorController() {
         Map<String, String> reqParams = ApexPages.currentPage().getParameters();
         language = reqParams.get('language');
         label = reqParams.get('label');
    }
}

Use this as pagereference in Aura methods
@AuraEnabled(cacheable=true)
    public static string getLabelTranslator(String label,String language) {
        try{
            PageReference r = Page.LabelTranslator;// the vf page
            r.getParameters().put('language', language);
            r.getParameters().put('label', label);
            return r.getContent().toString();
        } catch(Exception e){
            return label;
        }  
    }

In the LWC component,
getLabelTranslator({label:"CustomLabelName", language:this.lang})
            .then(result => {
                this.cslabel = result;
            })
            .catch(error => {
               // this.error = error;
            });

 
akash adminakash admin
Hi @Priyanka, 
I implemented your suggested code. The issue is I am getting the same string in return without getting converted in new language. 
Can you suggest if any thing else I need to do for conversation ? 
Priyanka Lakhani 1Priyanka Lakhani 1
Hi @Akash, can you please check the same thing by passing page parameters to page? Hit in the browser https://instanceName/apex/VFPageName?language=fr&label=LabelName
akash adminakash admin
Hi @Priyanka, 
I tried the link above with all values. It shows in english only for all languages.
Niels KeuningNiels Keuning
Hi Akash,

The provided example by Priyanka works fine for me. Just to be sure, you have added translations for the label you're testing it with? If there are no translations, it always returns the 'master' value, which is in most cases English.

I've copied the example, just added stuff where needed. For a complete overview, see below. Almost all is from the example of Priyanka, I just added some things to actually get it to work.
You can add this to a record page layout to test.

LabelTranslator.page
<apex:page showHeader="false" sidebar="false" controller="LabelTranslatorController" language="{!language}" standardStylesheets="false" contentType="application/json">
{!$Label[label]}
</apex:page>

LabelTranslatorController.cls
public with sharing class LabelTranslatorController {

    public String language { get; set; }
    public String label { get; set; }
        
    public LabelTranslatorController() {
            Map<String, String> reqParams = ApexPages.currentPage().getParameters();
            language = reqParams.get('language');
            label = reqParams.get('label');
    }
}

LWC labelTranslatorTest
HTML:
<template>
    {cslabel}
</template>


Javascript:
import { LightningElement, track } from 'lwc';
import getLabelTranslator from '@salesforce/apex/LabelTranslatorTestController.getLabelTranslator';

export default class LabelTranslatorTest extends LightningElement {

    @track cslabel;
    connectedCallback() {
        getLabelTranslator({label:"Test_VF_translation_label", language:this.lang})
        .then(result => {
            this.cslabel = result;
        })
        .catch(error => {
           // this.error = error;
        });
    };
}

Meta file:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>49.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>

LabelTranslatorTestController (used by LWC):
public with sharing class LabelTranslatorTestController {
    @AuraEnabled(cacheable=true)
    public static string getLabelTranslator(String label,String language) {
        try {
            PageReference r = Page.LabelTranslator;// the vf page
            r.getParameters().put('language', language);
            r.getParameters().put('label', label);
            return r.getContent().toString();
        } catch(Exception e){
            return label;
        }  
    }
}

Custom label with a Dutch translation:
User-added image
 
akash adminakash admin

Thanks @Niels and @priyanka.

I got the results. I was missing to enable the settings from my ORG. 
Thanks for your update,