Building a custom widget for Zoho CRM: build, test and deploy step by step

October 15, 2026

A practical guide to building a custom Zoho CRM widget: editions and permissions, the zet commands, testing inside CRM through External Hosting, and the pitfalls that slow delivery.

Abstract layered panels slotting into a larger frame, suggesting a custom component embedded inside a CRM screen

Building a custom widget for Zoho CRM: the short answer

Building a custom widget for Zoho CRM means writing a small web page with Zoho's JS SDK, testing it with the Zoho CLI, then packing it and adding it to CRM. You need the Professional, Enterprise or Ultimate edition. You also need a user profile with Developer Permissions switched on.

A widget is an embeddable UI component that you create and add to Zoho CRM. It often works with data from a third-party application. In Zoho's words, you can "directly embed UI components in a CRM and use the data from a third-party application to perform actions".

The build follows the same path every time:

  1. Create a project with the zet init command.
  2. Write the widget page in the project's app folder.
  3. Run it locally with zet run.
  4. Test it inside CRM through External Hosting, ideally in a sandbox account.
  5. Check it with zet validate and pack it with zet pack.
  6. Host the packed widget internally or externally.

The sections below follow that order. They also cover when a widget is worth the effort and where builds tend to go wrong.

When a custom Zoho CRM widget is worth building, and when it is not

A custom Zoho CRM widget is worth building when your users need to see or act on something that standard fields, layouts and related lists cannot show. The clearest case is data that lives outside CRM. Zoho's own example is a widget that displays a heatmap of the distribution of sales in a city.

A widget is code, so it carries a maintenance cost that a field or a layout change does not. Someone has to own the source files, test changes and repack the widget when it needs updating. If a field, a layout rule or a workflow already solves the problem, start there. Our post on customising your CRM without code covers those options.

A widget is also the wrong tool for storing new kinds of data. It displays and edits data, but it does not give you a new data structure. If you need new records and relationships, read how to choose between custom modules and a Creator app first.

Before you commit, answer three questions:

  • Does the user need this information at a specific point inside CRM, not in a separate tool?
  • Does the data come from somewhere CRM cannot show natively?
  • Will someone in your team or at your partner maintain the code after launch?

Three yes answers make a strong case for a widget.

Where a widget can appear inside Zoho CRM: eight placements

A Zoho CRM widget can sit in eight places, according to the Zoho CRM widgets overview. Choosing the placement is the first design decision, because it sets when the user sees the widget and what record it relates to.

The eight widget types Zoho lists are:

  • Dashboard
  • Web tab
  • Custom Button
  • Custom Related List
  • Wizard
  • Signal
  • Settings
  • Blueprint

Pick the placement by asking where the user is when they need the information. A sales manager reviewing performance works in a dashboard. A salesperson preparing a quote works on a record. A widget tied to a record can react to the record being opened. Zoho's documentation describes a PageLoad event that is "triggered whenever an entity Page (Detail page) is loaded".

An event is something the browser or the user does. Registering an event means defining a function that runs when that event fires. For a record-level widget, PageLoad is usually the event that gives the widget its starting point.

Before you start: CRM edition, Developer Permissions and tools

You need three things before building a Zoho CRM widget: the right edition, the right permission and the Zoho CLI. Check all three before anyone writes code.

Edition and widget limits

Widgets are available in the Professional, Enterprise and Ultimate editions of Zoho CRM. Zoho states a maximum of 200 widgets in Enterprise Edition and 200 in Ultimate Edition. Few organisations come near that limit, but it is worth knowing if many teams build their own.

Developer Permissions

The profile you use to access widgets must have Developer Permissions enabled. Go to Setup > Users and Control > Security Control, select the profile and enable Developer Permissions. Give this permission to the people who build and maintain widgets, not to every user.

Tools

Zoho states that you can create a widget once the Zoho CLI is installed. The CLI is the command line tool behind the zet commands in this guide. Any IDE will do for the code; Zoho suggests Visual Studio Code, WebStorm and Atom. Any client-side framework works too, from plain JavaScript to ReactJS.

If your team uses AI coding tools, Zoho has introduced a zoho-crm skill, a SKILL.md file. It helps tools such as Claude Code, Codex, Cursor and VSCode work with CRM developer tools, including widgets. If CRM configuration itself is still new to your team, our intermediate Zoho CRM guide is a useful starting point.

Creating the widget project with zet init and the JS SDK

A Zoho CRM widget project starts with the zet init command, which displays a list of Zoho services for creating a project template. The commands below cover the whole life of a project. Run them in a terminal, one at a time, in the order shown. Skip the npm line unless you build with ReactJS.

# create a new widget project and pick the service from the list
zet init

# then open a terminal in the new project folder

# ReactJS projects only: install React for this project
npm install react react-dom react-scripts

# host the widget locally for testing
zet run

# check the project against file and size limitations
zet validate

# pack the project; the ZIP file appears in the /dist folder
zet pack

Most readers change nothing in these lines. Leave out the npm line for a plain JavaScript widget. Run zet validate and zet pack again every time you change the code.

After zet init, the widget's HTML file is in the app folder and is named widget.html by default. Your page talks to CRM through the API helpers in Zoho's JS SDK. The Create Widget page in Zoho's developer documentation names the core calls:

  • ZOHO.embeddedApp.init() initialises the widget and starts listening to events in CRM.
  • ZOHO.CRM.CONFIG.getCurrentUser() returns user information such as name, ID, role and profile.

Widgets also support ZRC, the Zoho Request Client. ZRC gives you one consistent syntax for API calls.

Building a Zoho CRM widget with ReactJS: the settings that differ

A ReactJS widget needs four settings that a plain widget does not. Zoho's Kaizen #136 post walks through them, and each one causes a blank or broken widget if it is missed.

Dependencies stay in the project

You install React with npm install react react-dom react-scripts. These dependencies are installed only for that project, so each widget carries its own.

Everything the widget renders lives in /app

All files required to render the widget must reside in the /app folder of the project directory. React builds its output into a /build folder. Kaizen #136 modifies the build script in package.json to replace the contents of /app with the files from /build.

Static files must resolve from the same folder

Add the key-value pair "homepage": "./" to package.json. During production, this tells the system to look for static files within the same /app folder. Without it, the system looks in parallel directories.

The index page has a different name

A typical widget's index page is /widget.html. For ReactJS projects it must be named /index.html. Use the right name wherever you enter the index file.

Zoho notes that this configuration is almost common to most client-side frameworks. The same four checks are a sensible starting point for Vue or Angular.

Testing a Zoho CRM widget locally and inside CRM through External Hosting

You test a Zoho CRM widget in two stages: locally with zet run, then inside CRM through External Hosting. The first stage proves the page works. The second proves it works with real CRM records and users.

Local testing with zet run

The zet run command hosts the widget locally. Zoho is explicit about the limit: "Locally hosted widgets can be tested on that machine only." A colleague on another laptop cannot see your local build.

Testing in CRM context

To test inside CRM, create a widget with External Hosting. Use the URL that zet run gives you as the Base URL. Zoho allows this in either a production or a sandbox account. Choose the sandbox, so a faulty widget never touches live records or live users.

At Svennis we point every new widget at a sandbox through External Hosting before production sees it, and we test it logged in as a user with the same profile as the people who will use it. That catches the permission and data gaps that an administrator's login hides.

Test the awkward records as well as the tidy ones. Open a record with empty fields, a record with many line items and a record owned by someone else. Record-level widgets start from the PageLoad event, so check the widget on every detail page where it appears.

Local testing proves the page works, while External Hosting in a sandbox proves it works in CRM. Local with zet run / Inside CRM via External Hosting. How you start it: Run zet run in the project folder / Create a widget with External Hosting, zet ru

Worked example: a Quotes widget that reads and writes line items

A widget that edits quote line items is a good worked example, because a Zoho community thread documents exactly where it gets difficult. The poster built a Zoho CRM widget on Zoho Embedded App SDK v1.2. The goal was to read and update custom fields on the line items of Quotes, such as Segment_wyceny and W_pakiecie.

The poster reports that some calls worked as expected:

  • Creating Quotes with line items using insertRecord worked.
  • Updating line-item custom fields using updateRecord with line_item_custom_fields worked.

Reading the same fields back was the problem. The poster reports that getRecord returns Product_Details for a Quote, but without the custom line-item fields. They were missing even when requested through the fields parameter.

A second attempt also failed. Calling getRelatedRecords with Product_Details returned a "relation name invalid" error. The reason, as the poster explains, is that Product_Details is a subform of line items, not a related list.

The lesson for your own build is simple. Prototype the hardest data call first, before you design screens around it. If the widget must read a value back, prove that it can on day one.

Validating, packing and deploying a Zoho CRM widget: the checklist

A Zoho CRM widget goes live after two commands and a hosting choice. zet validate checks whether the project adheres to file and size limitations. zet pack then packs the project for upload to Zoho CRM and places the ZIP file in the /dist folder.

Zoho states that a tested widget can be packaged and hosted internally or externally. The table below sets out the full sequence, from permissions to deployment, as a checklist you can tick off.

StepCommand or settingWhat it gives you
1. PermissionsSetup > Users and Control > Security Control, Developer PermissionsA profile that can access widgets
2. Createzet initA project template with widget.html in the app folder
3. Run locallyzet runA local URL, testable on your machine only
4. Test in CRMExternal Hosting, Base URL from zet run, sandbox accountThe widget working inside real CRM pages
5. Validatezet validateA check against file and size limitations
6. Packzet packA ZIP file in the /dist folder
7. DeployInternal or external hostingThe live widget in its chosen placement

Keep the source files and each packed ZIP under version control. When a widget misbehaves after an update, the previous ZIP is your fastest way back.

Common Zoho CRM widget pitfalls we see in delivery

Most failed widget builds fail for a handful of repeatable reasons, not for hard technical ones. These are the ones to check before you report a widget as finished:

  • Wrong index page name. ReactJS widgets need /index.html, not /widget.html.
  • Missing homepage setting. Without "homepage": "./", a React build looks for static files in the wrong place.
  • Local testing only. A widget tested with zet run alone has never met real records or real profiles.
  • Methods that do not exist. The community thread above confirms that ZOHO.CRM.WIZARD.Post is not an SDK method. Check every call against Zoho's documentation.
  • Subforms treated as related lists. Line items in Product_Details are a subform, so related-list calls fail.

Widgets that call other apps add a further risk around credentials. Zoho's Building extensions #7 post shows a Zoho Projects extension that searches Zoho Desk articles. It uses a connection, a link to a third-party application that lets you work on its data safely. The plugin-manifest.json file includes the connection and the widget.

That same example hardcodes the Zoho Desk org ID in a request header. A hardcoded ID keeps a tutorial short, but it ties a widget to one organisation. Treat any hardcoded ID or key in a client build as a defect to fix.

Older forum threads mention a problem with widget heights in Client Script popups and flyouts. A Zoho moderation update states that this issue has been resolved.

What a custom Zoho CRM widget means for a UK business

For a UK business, a custom Zoho CRM widget is mainly a decision about edition, data and ownership. The technical steps are the same wherever you operate.

Edition

Widgets are available only in the Professional, Enterprise and Ultimate editions. If your firm runs a lower edition, the cost of upgrading belongs in the business case. A widget that saves a few clicks rarely justifies an edition change on its own.

Data leaving CRM

Many widgets exchange data with a third-party application. Decide which customer fields the widget may send or display, and record that decision with whoever handles data protection in your organisation. Zoho CRM also offers field masking to keep sensitive customer data private. Check how a widget behaves for users who should only see masked values.

Ownership of the code

A widget is a set of files and a packed ZIP. Agree in writing who holds the source, who may change it and who tests changes. This matters most when an outside developer builds the widget and your own team inherits it.

Who uses it

Developer Permissions belong to a small group. Limit them to the people who build and maintain widgets.

Next steps for your first Zoho CRM widget

Your first Zoho CRM widget should be small, record-level and tested in a sandbox before anyone sees it in production. Work through these steps in order:

  1. Write down the one piece of information users need, and where in CRM they need it.
  2. Check that a field, layout or workflow cannot already do the job.
  3. Confirm your edition is Professional, Enterprise or Ultimate.
  4. Enable Developer Permissions on the profile your developer will use.
  5. Install the Zoho CLI, run zet init and prove your hardest data call first.
  6. Test through External Hosting in a sandbox, logged in as a typical user.
  7. Run zet validate and zet pack, then deploy and keep the ZIP.

If the widget is one part of a wider change to how your team uses CRM, look at the whole setup first. Our Zoho CRM implementation and consulting page explains how we scope that work. It is also the place to start if you would rather have the widget built and maintained for you.

Sources

Looking for a Zoho partner in the UK? Svennis has been a Zoho Premium Partner since 2011, with more than 200 implementations delivered. See how we work as a UK Zoho Partner.