Trail Map โ€บ Use-Case Catalog โ€บ Component Library
๐Ÿงฉ Customization ยท Setup

Component Library: Build Your Own Widgets, Safely

How to add a small custom panel to a record page โ€” like a lead score summary โ€” without a developer ever touching the CRM's core code.

4
Tabs
~12 min
Time to Complete
80 pts
Available
1 Badge
Design System Curator

Why "just add one small widget" is usually hard

JL
Jordan Lee ยท Sales Operations Admin

"I just want a little box on the Lead page showing our lead score and a quick summary. I don't need a whole new feature, and I definitely don't want to file a request with engineering just for that."

A "widget" is a small, self-contained panel of information, like a little box on a page. These small, page-specific widgets are too minor for a full engineering project, but too custom for the standard record layout โ€” the normal arrangement of fields on a page.

Admins need a safe way to add their own mini-panels, without any risk of breaking the rest of the CRM, or seeing data they shouldn't.

๐Ÿ’ก
What you'll be able to do
Admins can build small custom panels for record pages themselves, in minutes โ€” with guardrails that stop a widget from ever seeing more of a record than it's explicitly allowed to.

One HTML file, a sandbox, and a field allowlist

A Custom Component is a single, self-contained HTML file โ€” with its styling (CSS) and behavior (JavaScript) built right in, no separate files needed. You pick which CRM object it attaches to. Then you explicitly check which fields it's allowed to read, and which of those it's also allowed to write back to.

Sandboxed execution"Sandboxed" means the component's code runs in an isolated, locked-down space with no network access. It can't call out to the internet, or reach anything outside the record it's attached to.
Talks to the record through an SDKAn SDK is a small toolkit of ready-made commands. Inside the component, JavaScript calls SmartLiteComponent.getRecord() to read the record and updateRecord(fields) to write to it โ€” never a direct database or API call.
Placed via Page Layout EditorOnce saved, a component is added to a record page from the Page Layout Editor โ€” the same tool you'd use to arrange every other section of the page. You can drop it in the sidebar as a small widget, or add it as a full-width section in the main body of the page if it needs more room (a related-list-style table, for example).
โœ…
Only checked fields are visible
Any field you don't explicitly mark as Readable is completely invisible to the component. It isn't just hidden on screen โ€” the component genuinely cannot see the rest of the record.

1 Build a simple Lead sidebar widget

Open Custom ComponentsGo to Settings โ†’ Custom Components โ†’ New Component.
Pick the object and fieldsTarget Object: Lead. Check the fields your widget needs to read, and only check Write for fields it should be able to update.
Paste the HTML, save, then place itPaste in a small self-contained HTML snippet, save the component, then add it to the Lead page layout's sidebar in the Page Layout Editor.

2 Give a widget real logic: call a Custom Class

A widget isn't limited to just showing its own record's fields. It can also call a Custom Class โ€” the same governed-script primitive covered in the Custom Classes & Pages trail โ€” to fetch or compute anything else it needs, using SmartLiteComponent.callClass(apiName, params) from inside the component's own JavaScript, exactly the way a Custom Page does.

Example: show every Contact under the Account you're viewingA related-list-style widget placed on the Account page needs to know which Account it's sitting on. SmartLiteComponent.getRecord() always includes the current record's own ID (as id) alongside whatever fields you checked Readable โ€” so the widget can pass that ID straight into a Custom Class that looks up Contacts for it.
Write the ClassA Custom Class like listAccountContacts reads the Account ID from PARAMS, queries Contacts with CRM.query('contact', 'account_id', PARAMS.accountId), and returns the list.
Call it from the widgetIn the component's script: SmartLiteComponent.getRecord().then(r => SmartLiteComponent.callClass('listAccountContacts', { accountId: r.id })), then render the returned list as a table.
Place it full-widthSince a contact list can run long, add it as a full-width Custom Component section on the Account layout instead of squeezing it into the sidebar.

Day-to-day: reps viewing the record

See the widget automaticallyOpen any Lead and the score summary panel is just there in the sidebar โ€” no extra click needed.

Day-to-day: admins

Build another widget for a different objectRepeat the same process for Opportunity, Case, or any other record type your team wants a quick panel on.
Adjust field access if a widget needs moreGo back into the component's setup and check an additional field as Readable or Writable, rather than rebuilding it from scratch.
Move it from sidebar to full-width (or back)In the Page Layout Editor, a component placed as a sidebar widget can be removed and re-added as a full-width section, or vice versa, without touching the component itself โ€” the same saved component works in either slot.
๐ŸŽฏ
What to try next
Look at the Custom Classes & Pages trail to write the Custom Classes your widgets call for real logic โ€” cross-object lookups, calculations, anything beyond the widget's own bound record.

Test what you learned

1. Can a custom component see every field on the record it's placed on?
No โ€” only fields explicitly checked as Readable are visible to it
Yes, it automatically has access to the whole record
2. Where does a custom component's code actually run?
In a locked-down, isolated space with no access to the internet
Directly on the CRM server with full database access
3. A widget on the Account page needs to look up all Contacts under that Account. How does it know which Account it's on?
It can't โ€” a component has no way to know its own record's identity
SmartLiteComponent.getRecord() always includes the record's own id, which the widget passes into a Custom Class via callClass
It queries the database directly for the currently open record
4. Where can a Custom Component be placed on a record's page layout?
Only the right sidebar
Either the right sidebar as a small widget, or a full-width section in the main body
Only above the page's header