Skip to content
Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
DictionaryCCustom S-Control
DevelopmentBeginner

Custom S-Control

A Custom S-Control is a retired Salesforce component that stored HTML, JavaScript, ActiveX, Java applets, or other browser content inside Salesforce metadata and ran it inside the Salesforce user interface.

§ 01

Definition

A Custom S-Control is a retired Salesforce component that stored HTML, JavaScript, ActiveX, Java applets, or other browser content inside Salesforce metadata and ran it inside the Salesforce user interface. S-Controls were the original way to extend and customize the Classic UI before Visualforce existed. Salesforce ran the stored content in the browser when a user opened a custom button, link, web tab, or page-layout section that pointed to the S-Control.

Salesforce deprecated S-Controls in the Spring '09 release and removed the ability to create new ones after January 2010. The official position is direct: Visualforce pages supersede s-controls, organizations that never used them cannot create them, and existing s-controls are unaffected and can still be edited. Because of that grandfather clause, working S-Controls still run in long-lived orgs even though no new ones can be made.

§ 02

How Custom S-Controls worked and why they were retired

What an S-Control actually was

An S-Control was a metadata record that held a blob of web content plus a name and a content type. Per Salesforce documentation, it could store or reference any content you can display or run in a browser, including a Java applet, an ActiveX control, an Excel file, or a custom HTML web form. Admins built one in Setup by entering S-Controls in Quick Find, creating a record, and pasting the markup or script into the body. The platform did almost nothing to the content. When a user hit a page that referenced the S-Control, Salesforce handed the raw HTML and JavaScript to the browser and let it run. That made S-Controls flexible and fast to write, since any front-end developer could drop in familiar web code. It also meant Salesforce gave you no markup language, no component library, and no server-side help. You were writing raw browser code that happened to live inside an org. Snippet S-Controls let you reuse one block of code across several others, which was the closest thing to modularity available.

Where S-Controls showed up in the UI

S-Controls were not a single feature; they were a content type you could attach in several places. Salesforce documentation lists the common ones: custom buttons, custom links, web tabs, page layouts, dashboards, and online help for custom objects. A custom button could fire S-Control JavaScript that called the SOAP API and updated records. A web tab could point at an S-Control that filled the whole content frame with a custom screen. Page-layout sections were a frequent home too. An admin could embed an S-Control directly on a record detail page so a panel of custom HTML rendered alongside the standard fields. This is why migrations drag on. A single org might reference dozens of S-Controls scattered across buttons, tabs, layouts, and dashboards, each one a separate place an admin has to find and rewire. There was no single list that showed every reference, so auditing meant walking each layout and button by hand.

Why Salesforce deprecated them

The core problem was that S-Controls ran entirely in the browser with no platform-managed structure. Every data read or write meant a JavaScript call out to the API and back, so a busy S-Control could fire many round trips and feel slow. The content did not automatically match the standard Salesforce look, so custom screens drifted away from the rest of the UI as the product evolved. There was no separation between presentation and logic, and no reusable component set, so each S-Control was a one-off slab of code. Security was the sharper issue. Browser-side JavaScript with access to the user session is easy to get wrong, and many early S-Controls were written with no review. Salesforce could not retrofit server-side rendering or a managed security boundary onto arbitrary HTML. Visualforce was built to fix exactly these gaps, so once it shipped, S-Controls became a legacy liability rather than a supported path forward.

Visualforce, the replacement

Visualforce arrived in 2008 and Salesforce positioned it as the structured successor. Instead of shipping raw HTML to the browser, Visualforce renders pages on the server using a tag-based markup language that resembles HTML. That server-side model brings several wins the official comparison highlights. Pages can automatically inherit the standard Salesforce styling, so a Visualforce page sitting on a record looks native without extra effort. Visualforce also separates the view from the logic. Markup defines what the page shows, while an Apex controller handles data and behavior, which means a lot of work happens server-side instead of through API calls from the browser. A standard component library gives you ready-made input fields, tables, and page blocks instead of hand-built HTML. The practical result is fewer round trips, less brittle JavaScript, and a page that stays consistent with the platform. For any S-Control built before 2008, Visualforce was the intended one-to-one upgrade.

Why some S-Controls survived to today

Deprecated does not mean deleted. Salesforce never force-removed working S-Controls, and the grandfather rule keeps them editable in orgs that already had them. So the only thing that retires an S-Control is a team choosing to rewrite it. In a mature org, that is real project work. Each S-Control has to be located, understood, rebuilt as a modern equivalent, tested, and swapped in everywhere it was referenced. The ones still alive in 2026 tend to be the low-risk leftovers. Static display panels and simple informational widgets keep working because Salesforce has not removed the rendering path for them. Anything that called the API or did real interaction was usually rewritten years ago, because the old SOAP patterns aged badly and the JavaScript broke as browsers changed. What remains is often code nobody has had a reason to touch, which is also a sign it might be unused entirely.

Migrating an S-Control in 2026

The modern target is a Lightning Web Component, not Visualforce. Visualforce still works, but it is itself an older framework, so rebuilding an S-Control as a Visualforce page just sets up a second migration later. Building one Lightning Web Component instead lands you on the active platform in a single pass. The exception is a static HTML S-Control with no logic, which can become a Rich Text component on a Lightning page with no code at all. A clean migration follows a few steps. Read the S-Control body and classify what it does: display data, run a button action, or render a form. Build the LWC equivalent, wiring any data access through an Apex method rather than browser API calls. Place it where the S-Control lived, on the page or as a quick action. Audit the JavaScript for old security mistakes while you are in there, since session handling and endpoint calls from that era often skipped permission checks. Test in a sandbox, because some S-Controls lean on Classic-only behavior.

§

Trust & references

Sources

Cross-checked against the following references.

Official documentation

Straight from the source - Salesforce's reference material on Custom S-Control.

Was this entry helpful?
Help us write better definitions. Quick reactions or detailed edit suggestions.

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 did a Custom S-Control store and run inside the early Salesforce interface?

Q2. What was the core security weakness that drove Salesforce to deprecate S-Controls?

Q3. What is the recommended target when migrating a surviving S-Control in a modern org?

§

Discussion

Loading…

Loading discussion…