Has anyone made a Lightning hack for a List Button that acts as a Hybrid for both Classic and Lightning? How'd you do it?

Context: I'm running a pilot of some users on Lightning and I have an Event custom List button with pre-filled values I tried to use an if statement that checks if the user is in Lightning and if so serve up the Lightning Page if not serve up the Classic one, the Lightning piece works, the Classic now gives me a "URL no longer exists" error.

Button URL:

(IF($User.UITheme) == 'Theme4d', 


Theme Detection: https://developer.salesforce.com/blogs/isv/2016/04/introducing-ui-theme-detection-for-lightning-experience.html

4 Answers 4


We had a need for the same, and Sander de Jong's answer on another question led me down the right path: you'll need to wrap the whole thing in a URLFOR expression. Note that this also means you'll need some slight changes in syntax, using + to concatenate instead of & and removing the braces and exclamation points from the merge fields.

I believe this might do the trick:

(IF($User.UITheme) == 'Theme4d', 
WhatId=' + Opportunity.Id +
who_id=' + $User.Id,

'/00U/e?what_id=' + Opportunity.Id +
'&who_id=' + $User.Id +
retURL=' + Opportunity.Id))}
  • this is absolute gold. in my testing today it worked with & to concatenate, but still poking on it.
    – gorav
    Sep 27, 2021 at 19:37

I did it slightly different and have confirmed working Summer 21.

Separate the URLFOR? I did.

Lightning uses BOTH defaultFieldValues and recordTypeId parameters along with field API names.

Classic does not use defaultFieldValues, rather, uses the Custom Field ID's and Value strings, CF notation for lookup fields (only) as well as the CF.._lkid. CFNotation is NOT needed for plain text fields like 'ChannelNameFieldID' below.

Note: Anything with <> notation below should be replaced with a recordId.

The names here are made up... In this case, pretend you have License Management as parent record, with Channels created as child records. This is a List Button for creating new Channel records of a specific record type with default fields (lookup and text). Good luck. Took me 3 hours to get this working. Grrr. Troy

URLFOR('/lightning/o/Channel__c/new?defaultFieldValues=IAD_LMR__c='+License_Management__c.Id + ',Channel_Name__c='+License_Management__c.Name+'_Channel&recordTypeId=<YOURRECORDTYPEID>'),


The approaches above work perfectly with one important caveat from my testing today - the button / link must be set to display in existing window. Display in new window caused the classic link to load in lex.

Once I switched to 'existing window without sidebar or header' it worked great for a custom link to a filtered report, using the classic URL hack and the official lex URL params.


I have another example: This is a list button on a related list.

Note: You cannot use retURL or saveURL in Lightning. You must use Actions for that.

Note: "Once I switched to 'existing window without sidebar or header' it worked great for a custom link... " Good catch gorav.

This example: We are creating an EVENT from a CASE.

URLFOR('/lightning/o/Event/new?defaultFieldValues=WhatId='+Case.Id+',WhoId='+Case.ContactId+',RecordTypeId=012300000001g4j,Subject=Pending Client Approval: '+Account.Name+' - Onsite'),
URLFOR($Action.Activity.NewEvent,null,[what_id=Case.Id,who_id=Case.ContactId,retURL='/'+Case.Id,RecordType='012300000001g4j',evt5='Pending Client Approval: '+ Account.Name+' – Onsite'], true)

Enjoy. Troy ~ Seattle

You must log in to answer this question.

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