A Salesforce Lightning Migration

Jason McLain
15 min readMar 11, 2019


Are you stuck in a rut? Tired of the same old boring (if functional) interface? Ready for something new and exciting? If so, then it may be time for your very own Lightning migration! As someone who recently went through the process I’m here to provide enlightenment by detailing what we went through in our migration. I’ll explain the process we used, the trials and tribulations we faced and conquered and the final outcome. I’ll also throw in some thoughts on what we could have done better, reasons to migrate, and handy links to documentation and Ideas that you should upvote. So read on and remember to upvote… Always upvote!


I was hired as a Developer for my current org in 2015 and I remember being thrilled to have a virtually pristine org to play with. There were a couple of hundred users, a handful of custom objects and virtually no custom code. There were three of us supporting it at the time and I recall discussing switching to Lightning and deciding against it due to feature parity — there were just too many features missing from Lightning at the time. Well, it’s four years later and that has changed a lot…

IMPACT is a fairly heavily customized Salesforce service organization that was established in 2012 and currently has a bit over three-thousand active users. There are around thirty product owners, many Roles and Profiles, and dozens of Record Types and Page Layouts for Cases, Events, Tasks, etc. Our primary Apps utilized the Service Cloud Console. We don’t have any Communities and so far we’re not using mobile Apps or Outlook integration (at least not officially).

We spent around six months preparing for our final migration. In the process we created a lot of improved functionality, made our interface much more consistent, and most importantly are now able to take advantage of the many improvements that are available for Lightning only.

The deployment itself went smoothly and took two devs around three hours to complete and test. We had a couple of bugs to deal with and a few complaints about the interface but our support team handled it with their usual professionalism and nobody was overwhelmed. I’ve been through much worse migrations. On the other hand there are several Lightning issues that can ruin your day…

Page Layouts

The Problem

It is not currently possible to assign Page Layouts specifically for an App or to Lightning users. You can do this with the new Lightning Layouts but not with standard Layouts. For us this meant that it was impossible to do any kind of staged rollout since we planned on making changes to Page Layouts.

Our Solution

Our way of dealing with this was creating new Lightning-specific Layouts and keeping them synchronized with any new changes deployed to production. Then we simply updated the Page Layout assignment when we did the final deployment. This meant that all testing had to be done in the full Sandbox which made the final deployment much more tedious and time-consuming. If we could have App-specific or Lightning-specific Layout assignment we could have done a staged rollout to production with much more rigorous testing and deployment would have been simple by comparison. Here’s an idea to upvote which would have saved us a lot of pain and frustration:

Set Page Layout on Lightning App by Record Page, not Record Type


The Problem

The next major roadblock to our progress was due to the fact that Actions cannot be shown as a button on Cases if Cases are Feed Enabled. Any Actions that are added will show up in the Chatter section of the Layout and not as a button.

This was compounded by a couple of other issues:

  1. There’s no close Case process in Lightning so if you have a complex closing process you’re going to have a bad time.
  2. “URL Hack” javascript buttons do not work in Lightning at all. We had several of these that we used for things like creating child Cases or a customized Case accept button.

If Actions worked like they do on other objects we could have just created custom Actions to close Cases or create child Cases and pre-populated the necessary fields but that’s not currently possible. I also tried using Flow buttons or URL buttons to launch Flows but either it didn’t appear in the highlights panel or it didn’t behave well in the console. I also tried using Actions in Tabs and that seemed to work at first but pre-populating fields doesn’t work if they’re on a Tab.

Our Solution

I ended up breaking the close Case process into two groups based on the complexity of their close Case process.

For the simple process I just created a custom field called Close Reason and populated it with the values from Case reason and made it dependent on the closing status. I put Close Reason in the main Layout and made it required so that it was required to close the Case but not during normal activity.

I had to create a new field because you can’t have a standard field dependent on another standard field. I also created a process that copied the close reason value to Case reason just for reporting purposes.

For the complex process I created an Action on a Tab and a validation rule that forced them to use the Tab to close the Case. This also required creating a separate Lightning Layout since there is no way to hide individual Tabs with visibility controls.

Of course this isn’t my preferred solution but it was the best I could do in the time we had. Eventually I’ll create a Lightning/Web/Flow component that will improve on the original process but so far there have been no complaints. I also made sure to demo this process early in our migration process and gave the affected product owners ample time to ask questions or request changes.

For the URL hacks I ended up using Flow components with the occasional embedded aura components. This worked pretty well and I used visibility controls to hide things from different groups or when they’re not valid. The main issue with this is that users are used to accessing these buttons from the Related List and now they have to look for them elsewhere. It’s a minor learning curve issue though, and functionality was maintained.

As part of this process I was able to improve functionality in a few places. The flow components have more detailed instructions and could provide additional guidance if we needed it. The ability to filter components is also great — I love being able to hide components based on field values, profiles, roles, etc. We also took advantage of this to clean up the Status picklist which enables us to use the Path button on Status in some instances.

Here are a few more ideas to upvote around these issues:


The Problem

We have a lot of Attachments and Attachments are not supported in Lightning. Standard Notes are also not supported but fortunately we’re not heavy note users. In Lightning these items have been replaced with new, separate Related Lists for Files and Notes.

Our Solution

What I discovered on investigation is that there is a checkbox in General Settings that will cause Attachments to be added to Files instead of Attachments. This works because the Attachments Related List is smart enough to show both Files and Attachments. It would have been great if Salesforce had done the same with the Files related list which would have saved us a separate migration… In any case if you enable this checkbox early in the process then you will have the recently added Files available. You’ll still have to migrate older Attachments and for us it was a multi-day process requiring a third-party Appexchange App.

Here are a couple of links to save you some time:

The Migration

The UI

We wanted to create a UI that is clean and easy to use and also maintain consistency. We also wanted it to work well in a Console. I created several different Layouts and presented them to our team and we ended up with a three-section Layout…

  • At the top a full-width panel for highlights, path, etc.
  • A three-quarter width main section for the main tab section with tabs for Details, Chatter, Close Case, etc.
  • A one-quarter width section on the right side that we use for narrow components like Related List Quick Links, Files Related List, and Flow Components.

Here’s a screenshot from my Dev Org to give you a general idea of how it looks:

I would have liked to have a pinned top section but all the pinned options for Console had left and right side panels which was just wasted space for us. I also tried creating a custom Lightning Layout but could never get the formatting to work. CSS is not my friend… What’s especially galling is that if I weren’t using the console the top section of the highlights panel with the buttons would be sticky by default…

In my opinion the final product is a big improvement over the Service Cloud console view we had been using. We were able to take advantage of a lot of the new functionality offered by Lightning, clean up the layouts, and make things consistent throughout our organization.

The App

Another big decision we made early on had to do with our App or Apps and what to call them. After some deliberation we decided to come up with a single App that would work for everyone instead of trying to break things up by product group. We did this for a couple of reasons:

  1. It will be much easier to support and train on.
  2. We have a lot of users that work with multiple product teams and we didn’t want them to have to constantly switch Apps.

We also took advantage of this to do a bit of branding and theming. We came up with a new App name, a nice looking new Icon for our org and a custom theme to tie it all together. This made the final product look much more polished and professional.

The Work

It was time for the actual work to begin. We created a regular cadence of short meetings similar to our daily Scrum to discuss the migration and address blockers. We broke everything up into user stories by object for the most part and by product team for the more complex conversions — Cases for example. All the work was done in the full Sandbox to avoid disrupting our production users.

The basic process we followed was to create a Lightning Page Layout for each object (more than one in some cases) and then clone the standard Page Layouts to new Layouts with a standard naming convention. Our naming convention for Page Layouts was basically LEX_Object_RecordType which made updating the Page Layout assignments on migration day much less confusing. Then we just had to test existing functionality and create new functionality for anything that didn’t work well…

We follow best practices in our Org which meant that most of our customizations worked fine in Lightning and just had to be thoroughly tested. Some functionality worked fine but didn’t behave well in the Lightning console. Other items like URL hack buttons and the Close Case process had to be replicated using different tools. This could mean creating an Action or Flow to replace buttons in the List View or Related Lists or new fields or Tabs.

We did our best to make as many improvements as possible in order to improve adoption. This meant cleaning up the Layouts wherever we could by removing fields that were moved to the Highlights Panel and reordering some fields to flow better. Another thing to take advantage of is the collapsible sections in the Lightning details page. The first section is normally hidden but if you make it visible then the users can collapse it to get it out of the way instead of having to scroll constantly.

We attempted to loop in product owners whenever possible for feedback on our progress and to gain insights on where further improvements could be made but since the work had to be done in the Sandbox it was much more difficult to get proper feedback.

The Final Days

Our next step, once the functionality was mostly done, was to work with our product owners to evaluate what we had done and give us feedback. Some of our product owners took the extra effort of getting their more active users to log into the Sandbox and go through their standard processes. This rooted out quite a few issues and allowed us to make several improvements. If more product owners had done this we might have avoided some of the issues we discovered on day one post-migration.

To prepare for our final migration we pushed much of the work we had done into production ahead of time. New Flows, Processes, Apps, Page Layouts, fields, etc. could all be deployed ahead of time and activated on the day of the migration. When the time came we simply updated the Page Layouts and assigned the Lightning Layouts. We also updated the Profiles by removing access to older Apps, granting access to the new App, and removing the ability to revert to Classic.

The final deployment happened at the end of our normal Sprint cycle when our users are used to seeing changes… It took about three hours for us to push the final Change Sets into production and make all the manual changes needed and to do follow-up testing.

Post Migration

The Day After

Even though the migration went smoothly there are always problems. The worst of these problems were caused by two new Salesforce bugs:

  1. The isClone method no longer works with Cases that are created in Lightning. We have Apex code that clears certain fields on cloned Cases which had to be rewritten.. I’m not sure how this happened since Lightning is supposed to be primarily cosmetic changes..
  2. Users could not change ownership. Our users are used to changing the owner of Cases to someone else and then taking ownership back when they’re done. This worked fine in Classic but not in Lightning. This was also a known issue and it was fixed but you have to contact salesforce for them to apply the fix for your org. For some reason this process took over six hours…

User complaints were mostly about speed and some deficiencies in certain UI elements. After a day or two caching took care of most of the speed issues. We also enabled the Akamai Content Delivery Network after double-checking with our COE. You can find information here:

Enable CDN to Load Lightning Experience Faster

We are still finding issues now and then but most of the time it’s a browser issue or user error. The few problems found since day one have primarily been interface issues or bugs that we have no control over and we’ve opened cases with Salesforce to have them investigated.


General Issues

Here’s a list of the major issues with the interface:

  • Too monochrome/washed out — the old interface wasn’t pretty but it did make information pop. Lightning does not do this well — it’s particularly bad at highlighting which fields are required as it does this with a tiny, almost invisible red asterisk that only appears in edit mode.
  • Too much white space — this has been somewhat alleviated with the addition of an option to switch from cozy to compact Layouts but information density still doesn’t match what they are used to in Classic which means more scrolling.
  • Can’t double-click on Multi-select values — they’re used to being able to simply double-click a value in the Multi-select UI and having it jump to the other column. Now they have to select the values and then click the little arrow in the middle to move it over. It’s much more time-consuming and I’m kind of shocked that it hasn’t been fixed by now.
    Idea to upvote
  • Multi-select UIs block both columns in the Layout — This causes a lot of extra whitespace and makes tabbing through the fields more cumbersome. If you attempt to make the Multi-select two-column it still renders in one column and blocks the other column. Basically Multi-selects are even worse than they used to be.
    Idea to upvote!
  • The working spinner/animation is missing — it isn’t actually missing but only renders at the top of the page. If they have scrolled down a bit and update a field and hit enter it looks like nothing is happening because the spinner isn’t on the screen. It would be nice if either the spinner popped up in the center of their display or maybe the page grayed out or something until it was done.
  • Scrolling back up to see the buttons in the highlights panel — this is due to not being able to make that section sticky as previously mentioned. Hopefully it will be addressed at some point or I’ll figure out enough CSS to do it myself. It would be nice if we could simply flag a section as being sticky instead of having to use a specific Lightning Layout
  • No recycle bin — fortunately our users don’t use the recycle bin much since they don’t have delete permission on many items but bear in mind that there’s no recycle bin in Lightning and the official Salesforce workaround is to switch to Classic to undelete items.
    Idea to upvote!

General Advice

Things I wish we’d done differently:

  • More interaction with the Product Owners — we should have had a regular cadence of meetings with them walking them through the UI changes and getting their feedback. This would also have been a great time for them to leverage some of the Lightning features like Paths, Flows, Macros, etc. to improve the user experience — or just to reorder some Page Layouts to streamline and improve the workflow.
  • More UAT — we only had a handful of users actually testing this in our Sandbox and they were all from a single product team. We should have tried to recruit more and had a regular meetings to discuss what they liked/disliked and make improvements where appropriate.
  • Centralized notes — there were only two devs working on this project and we did a good job of dividing up the work and keeping our own notes but having a central location to keep notes would have been beneficial and helped avoid confusion.
  • Centralized support announcements — we have a system for users to create internal support tickets but we needed a way to notify users about known issues and when issues had been addressed. We created an announce only Chatter group to help with this but something built into our support system would have been better. In the future we might create something like Salesforce’s Known Issue system where users can add themselves to the list of affected users.

Final Thoughts

Worth It?

I’m sure after all this you have to be wondering if you should even bother? Why go to all this trouble? The obvious answer is that you have to upgrade to have access to all the new features Salesforce has released that are only supported by Lightning. There are other reasons, though…

For us a big one was improving consistency… We did our best to make the new Layouts as consistent as possible which makes our users happy and also benefits our support and training teams. We also worked hard to clean things up along the way and improve the user experience. In general it was an opportunity to overhaul and improve our org in many ways and we took advantage of this wherever possible.

Another benefit of the new architecture is that you will be able to leverage more readily available full-stack developers to create new functionality rather than having to rely on Salesforce-specific developers. This is especially true with the addition of Lightning Web Components Spring ’19 release:

Introducing Lightning Web Components

Of course you’ll also be able to leverage all the new functionality — a lot of which we haven’t gotten around to using… Just to name a few:

  • Actions — with the notable exception of Cases, Actions are very powerful and can be used in lots of different ways from simple field updates to calling Flows for more complex updates.
  • Flow components — easily add interactive sections on your Layouts that can perform complex actions with no coding required
  • Path/Guided Action Components — provides detailed guidance about steps that need to be taken
  • Kanban list views — allows users to visually bucket items and move them between these buckets simply by dragging them.
  • Components filter — gives you fine control of which components are visible on a page which allows you to only show what is needed or to hide a component once an Action is taken.
  • Pre-built components — There are many free or paid web components available from the Salesforce App store or other sites.
  • Einstein — Access to machine learning features which can do everything from recommending users to follow to guiding the user on the Next Best Action to take with a customer.

Thanks For Reading

Hopefully this will provide some of you with the inspiration to tackle the Lightning conversion yourself and will give you an idea about what to look out for.

Special Thanks To:

  • My team — who made all the difference in getting the migration done well and on time.
  • Troy, Miriam, and Jason — who reviewed this document and gave me much needed feedback and advice.
  • My wife Cyndi — who put up with my near-constant complaining about Lightning for six months.
  • The Salesforce Exchange Discord — who are always there for me when I need Salesforce advice or just someone to talk to.



Jason McLain

CRM Professional since 1996 — Salesforce Professional since 2010. Currently the Senior Developer for UnitedHealth’s largest Salesforce Org.

Recommended from Medium


See more recommendations