onClick JavaScript
onClick JavaScript was the Salesforce Classic feature that let admins build custom buttons and detail-page links whose action ran a block of JavaScript instead of opening a URL.
Definition
onClick JavaScript was the Salesforce Classic feature that let admins build custom buttons and detail-page links whose action ran a block of JavaScript instead of opening a URL. The JavaScript could call the Salesforce AJAX Toolkit (sforce.connection), update records, redirect the browser, prompt the user, or invoke any other browser-side logic. It was the dominant pattern for one-click record updates and quick popup actions before Lightning Experience launched.
The Behavior is retired in Lightning Experience. onClick JavaScript buttons do not work in Lightning Experience, the Salesforce mobile app, or any modern UI. Salesforce stopped supporting them in Lightning rendering as of the Spring 2018 release. Admins migrating from Classic must replace every onClick JavaScript button with a Lightning Quick Action, a flow, a Lightning Web Component, or an Apex-backed Visualforce page. The feature still appears in Setup for backward compatibility with Classic-mode users, but any new Lightning org should treat onClick JavaScript as a legacy artifact, not a build target.
Why onClick JavaScript existed, why it broke in Lightning, and what replaced it
What onClick JavaScript actually did
An onClick JavaScript button had a Behavior of Execute JavaScript and a Source of script text. When the user clicked the button on a record detail page, Classic ran the JavaScript inline. Common patterns were calling sforce.connection.update to flip a single field (Close Opportunity, Mark as Active), opening a popup with location.href, or building a complex sequence that updated several related records in one click. It was the closest thing Classic had to inline custom logic on a record page, short of writing Apex and Visualforce.
Why Lightning Experience killed the feature
Lightning Experience uses a different rendering model: components are isolated, the DOM is virtualized by the Lightning framework, and direct browser-DOM JavaScript from buttons would bypass security boundaries (Content Security Policy, Locker Service). Lightning enforces CSP that blocks arbitrary script execution from page elements, which is what onClick JavaScript fundamentally relied on. Rather than half-supporting the feature with security holes, Salesforce blocked it entirely in Lightning rendering. Classic kept it working because Classic is the older rendering pipeline without CSP enforcement.
The replacement options in Lightning
Most onClick JavaScript buttons map to one of four replacements. Quick Actions handle single-field or limited-field updates with a simple modal form. Flow-backed actions run a flow when the button is clicked, supporting complex logic without code. Lightning Web Components handle custom UI with full programming flexibility. Apex actions (called via flow or LWC) handle server-side logic. The choice depends on what the original JavaScript did. Most legacy buttons fit cleanly into a Quick Action or a flow; only complex multi-step ones require LWC.
Tools for finding existing onClick JavaScript buttons
Salesforce ships the Configuration Conversion Tool and a JavaScript Buttons report that scans an org for every active onClick JavaScript button, lists its source, and recommends a Lightning replacement. Run this report on every Classic org before flipping to Lightning Experience. The Salesforce Lightning Experience Migration Assistant also includes a JavaScript Button Migration step that walks through each button systematically. Skipping this audit is how Lightning migrations break end-user workflows that admins never knew existed.
The AJAX Toolkit and sforce.connection
The bulk of onClick JavaScript called the AJAX Toolkit, a JavaScript wrapper around the SOAP API. sforce.connection.update(records), sforce.connection.query(SOQL), sforce.connection.dml all returned synchronous-looking responses that the button code could process. The toolkit is also retired in Lightning. Code that called it through onClick JavaScript breaks in two ways: the button does not execute, and even if it did, the underlying toolkit would not be available. Some legacy Visualforce pages still load the toolkit; that usage is also deprecated and slated for retirement.
Common JavaScript button patterns and Lightning equivalents
The Close Opportunity Won button (set Stage to Closed Won, set Close Date to today, save) becomes a Quick Action with two predefined field values and a Save action. The Send for Approval button becomes an Approval Process trigger or a flow with the Submit for Approval action. The Update Related Records button becomes a flow that loops through child records. The Open Custom Modal button becomes a Lightning Web Component with a lightning-button trigger and a modal launcher. Each pattern has a clean Lightning equivalent; the work is identifying which pattern applied to each legacy button.
Classic users and the long tail
Some orgs maintain Classic for specific user groups (call center reps using Salesforce Console for Service Classic, legacy integrations that depend on Classic page layouts) long after the rest of the company moved to Lightning. In those niches, onClick JavaScript still works as long as the user stays in Classic. Salesforce has not announced a Classic shutdown date, but feature freeze on Classic has been in effect since 2019. Any new build on Classic is technical debt; budget for the Lightning migration even if Classic is currently working.
Auditing and replacing onClick JavaScript buttons during a Lightning migration
The migration pattern is consistent across orgs: inventory, classify, replace, retire. Each step has tooling support but requires manual decisions per button.
- Run the Lightning Experience Migration Assistant
Setup, Quick Find, Lightning Experience Transition Assistant. Open the JavaScript Button Migration step. The tool scans every active onClick JavaScript button, lists source code, and suggests Lightning replacement patterns.
- Classify each button by replacement type
Group buttons into four buckets. Simple field updates go to Quick Action. Multi-step logic goes to Flow. Custom UI goes to Lightning Web Component. Server-side processing goes to Apex called from Flow or LWC.
- Build the Lightning equivalent
Implement each replacement in the appropriate tool. For Quick Actions, configure the action object, fields, and default values. For Flows, build the flow and add as an Action element on the page layout.
- Add the new action to the Lightning record page
App Builder, open the record page, add the action to the Highlights Panel or to the Actions component. Configure the action visibility per record type or per user profile if the original button had access restrictions.
- Deactivate and remove the old button
Once the Lightning equivalent is verified working in Lightning, deactivate the original onClick JavaScript button. Delete fully only after a release cycle to allow rollback if the new action has bugs.
Quick Action (simple field update), Flow (multi-step logic), Lightning Web Component (custom UI), Apex Action (server-side processing). Pick per button based on what the original JavaScript did.
Lightning Experience Migration Assistant scans buttons. Third-party tools like Elements.cloud provide deeper button-by-button analysis with proposed Lightning equivalents.
Migrate buttons feature by feature, not all at once. Pair each button replacement with end-user training and a one-release rollback window.
Specific user groups may stay on Classic during the migration. Buttons can coexist in Classic and Lightning, with Lightning users seeing the new action and Classic users seeing the old button.
- onClick JavaScript buttons do not work in Lightning Experience. Users who switch from Classic without a migration find their daily-used buttons silently disabled.
- The AJAX Toolkit (sforce.connection) is retired in Lightning. Even Visualforce pages calling it break in Lightning rendering.
- Quick Actions support single-object field updates only. Multi-object or cross-record logic needs a flow or LWC; a Quick Action will not cover the case.
- Lightning CSP blocks arbitrary script execution. Embedding JavaScript directly in a Lightning page (via a custom Visualforce page in an iframe) often fails on security review even if it technically works.
- Buttons with sharing rule logic (the user only sees the button if they meet criteria) need their visibility logic moved into the Lightning page action criteria, which uses a different rule syntax than the legacy URL-driven visibility.
Trust & references
Cross-checked against the following references.
- JavaScript Buttons RetirementSalesforce Help
- Migrate JavaScript Buttons to LightningSalesforce Help
Straight from the source - Salesforce's reference material on onClick JavaScript.
- Lightning Experience Migration AssistantSalesforce Help
- Quick Actions OverviewSalesforce Help
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Test your knowledge
Q1. What is onClick JavaScript?
Q2. Does it work in Lightning?
Q3. What replaces it?
Discussion
Loading discussion…