9

The lost simplicity

The docs discourage the use of this pattern

<a href="/XXXXXXXXXXXXXXXXXX">Salesforce record ID (DON'T DO THIS)</a>

Instead we should

Use Navigation Events

Use one of the navigation events for consistent behavior across Lightning Experience, Salesforce app, and Lightning communities.

  • force:navigateToList
  • force:navigateToObjectHome
  • force:navigateToRelatedList
  • force:navigateToSObject
  • force:navigateToURL

But this is NOT good enough!

Without a present href="" the usability is crippled in a dramatic way:

  • bookmarking the link is impossible
  • middle-click or control-click or right-click->popup to open in an other tab or window is impossible

I found the post here Why not use href="/id" or href="#/sObject/id/view" in Lightning?

Until Summer '18 I've used these patterns

#/sObject/id/view

But now with the new URL-scheme it does not work anymore. It simply stays on the given page.

Relative URLs worked earlier too, but now they reload the entire page instead of navigating to just the view in the given page. In other words: the single-page-app concept is broken and the navigation show the Summer'18 logo and it is very very slow.

Having a js-controller method funneling all the events also is overkill for my taste. A PERFECT navigation should work out-of-the-box in a 100% declarative way without touching into the guts of js-functions.

So how can we have it ALL?

  • present and working href (or alternative) to prevent the loss of bookmarking and rightclick-open-in
  • avoid reload of the page
  • if possible have all this done declarative

Has anyone a pattern or component for ALL that?

I'm thinking of writing my own "link component" now... but I want to avoid it (to avoid support, maintenance, etc). And I don't want to reinvent the wheel.

Update

Now with tears in my eyes, I've written my own compo for that... As far as I've quickly tested, it seems to work supporting all the above requirements. But I would like to get rid of it again, ASAP! I named it elfLCXLink.cmp and it looks like this:

<aura:component>
    <aura:attribute name="href"    type="String"      default="" access="global" />
    <aura:attribute name="onclick" type="Aura.Action"  />
    <a href="{!v.href}" onclick="{!c.onClick}">
        {!v.body}
    </a>
</aura:component>

Controller:

({
    onClick : function(cmp, evt, hlp) { 
        evt.preventDefault();
        var e = $A.get("e.force:navigateToURL");
        e.setParams({
            "url"               : cmp.get("v.href"),
        });
        e.fire();
        if(cmp.get('v.onclick')) {
            $A.enqueueAction( cmp.get('v.onclick') );   
        }
    }, 
})  

Usage Example

<c:elfLCXLink href="/lightning/r/Account/0010Y00000IMSUNQA5/view" >
    LEX Link
</c:elfLCXLink>
<br/>
<c:elfLCXLink href="/0010Y00000IMSUNQA5" >
    Aloha Link
</c:elfLCXLink>
  • What is µµ? why do you need afterScriptsLoaded? – kurunve Jul 3 '18 at 11:13
  • 1
    @kurunve, sry you are right buddy! I'm using my own js-framework to make things shorter... posting here, i've to strip always. here i was incomplete. now it's cleaned up again. hopefully. no afterScriptsLoaded() needed. no APEX needed. also onclick it totally optional. – Uwe Heim Jul 3 '18 at 11:15
  • I had (and still have) similar problem too, with one small difference -- I really needed that to be working as lightning out, so it does smooth redirect to a record in LEX, and normal one in Classic, but havent solved that yet. – kurunve Jul 3 '18 at 11:19
  • @kurunve have you tried my compo? Havent tested for lightning-out. If it does not work, you should ask a different question. – Uwe Heim Jul 3 '18 at 11:20
  • Well, your component solution works perfect, and I have ended up with something similar before. My previous comment was more about "And I don't want to reinvent the wheel.", where I totally agree that there should be build in way to do it. – kurunve Jul 3 '18 at 11:25
5

From Summer18 I think one should use lightning:navigation component and the pagereference object that comes along with it .

The link here shows various possibilities within the lightning experience .

Lightning experience internally uses these navigation API so being consistent with the same for partners makes sense .

Here is a simple example

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes">
   <aura:attribute name="url" type="String"/>
   <aura:attribute name="pageReference" type="Object"/>
   <aura:handler name="init" value="{! this }" action="{! c.init }"/>
   <lightning:navigation aura:id="navService"/>
   <a href="{!v.url}">Link</a>
</aura:component>

Controller code

({
init : function(cmp, event, helper) {
    var navService = cmp.find("navService");
    // Sets the route to /lightning/o/Account/home
    var pageReference = {
        type: 'standard__objectPage',
        attributes: {
            objectApiName: 'Account',
            actionName: 'home'
        }
    };
    cmp.set("v.pageReference", pageReference);
    // Set the URL on the link or use the default if there's an error
    var defaultUrl = "#";
    navService.generateUrl(pageReference)
        .then($A.getCallback(function(url) {
            cmp.set("v.url", url ? url : defaultUrl);
        }), $A.getCallback(function(error) {
            cmp.set("v.url", defaultUrl);
        }));
   }
})

Also you can navigate using the navigate API methods as shown

<lightning:navigation aura:id="navService"/>
  <a href="{!v.url}" onclick="{!c.handleClick}">Link</a>
 <lightning:button label="Navigate" onclick="{!c.handleClick}"/>

controller function

({
handleClick: function(cmp, event, helper) {
    var navService = cmp.find("navService");
    // Uses the pageReference definition in the init handler
    var pageReference = cmp.get("v.pageReference");
    event.preventDefault();
    navService.navigate(pageReference);
  }
})

I don't have a pattern but if anyone manages to build a pattern use lightning:navigationAPI along with the various pagereference types .


(Update from Mark:)

There's a pretty big caveat with the new navigation component currently. (Docs link)

These navigation resources are supported only in Lightning Experience and the Salesforce mobile app. They’re not supported in other containers, such as Lightning Components for Visualforce, Lightning Out. This is true even if you access these containers inside Lightning Experience or the Salesforce mobile app.

  • 1
    Wow, a link to the documentation that actually works! – Adrian Larson Jul 3 '18 at 21:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.