Skip to main content

Register a Custom Control

Goal​

Install a Custom Control into an environment by uploading its package, so it can be mounted on a Model-Driven form field.

Looking for how to build the control rather than install one? This page assumes the control already exists and has been packaged. Writing it — the fixed props contract, which field types it can substitute for, the value states it must handle, testing, and packaging — is Build a Custom Control.

Prerequisites​

  • You are signed in to the Admin Control Center as a platform administrator.
  • A publisher and a solution owned by that publisher already exist.
  • The environment you are installing the control into is active.
  • You have the control's package — the .zip produced by npm run pack in the control's own project. It is usually written to that project's package/ folder and named after the control, for example par_signature_pad-1.2.3.zip.

Steps​

  1. Choose the environment the control should be installed in, from the selector in the top bar.
  2. Open Solutions, then open the solution the control belongs to.
  3. Select Custom Controls in the solution's left navigation (or the Custom Controls card on the solution overview). The page lists the controls this solution has already installed in the selected environment.
  4. Select New. A panel opens at the side of the screen.
  5. Choose the control's package file.
  6. Select Register custom control. The control appears in the list for that solution and environment, on the solution's overview under Custom Controls, and in the form designer's field palette.

That is the whole form. There is nothing else to fill in because the package already says all of it: the control's logical name and display name, the Module Federation scope and exposed module its build actually used, the entry file to serve, and the field types it can substitute for. Those last two used to be copied out of a bundler config by hand, and getting either wrong produced one symptom — the control simply did not load — with nothing to say which of the two was wrong.

Uploading again replaces the installed build. That is the normal loop while working on a control: change it, run npm run pack, upload it again. You do not have to remove the old registration first. The Version column shows which build is installed, so you can check that what is running is what you last packed.

To remove a control, tick its row and select Remove. This uninstalls it from the environment and deletes its stored package; the solution keeps its component reference, because other environments may still have the control installed.

Where the control's code lives​

The package's bytes are stored by the platform and served from the platform's own address. Nothing is fetched from an external host, so:

  • the solution is self-contained — exporting it carries the control's code, and importing it into Test or Production installs a working control rather than a pointer to wherever it was built;
  • there is no URL to allow-list, and no URL to go stale.

A control's code does not need to be uploaded as Web Resources. Web Resources are for standalone files you author and reference by name — a stylesheet, an image, a script — not for a control's build output.

What happens behind the scenes​

The archive is checked before anything is stored: its size, how many files it holds and how large it expands to, that no file inside it names a path outside its own folder, that every file is a type the platform serves, and that its manifest matches the published package schema. Then the control's logical name is checked against the owning publisher's prefix.

The package is stored whole, and unpacked the first time the control is actually requested. That is why a control keeps working after the platform restarts, and why it works the same on every server: the stored package is the real copy, and the unpacked files are only a cache that rebuilds itself.

Installing the control in one environment does not install it in any other; it travels when its solution is exported and imported.

Troubleshooting​

  • "The package has no 'parsware.json' at its root." — the file uploaded is a plain build output rather than a package. Build it with npm run pack in the control's project.
  • "Custom control … must start with the publisher prefix …_." — the logicalName in the control's package.json does not begin with the owning publisher's prefix. Change it there and pack again.
  • "The package holds … files; the maximum is …" — almost always a node_modules folder that ended up in the archive. Pack the build output, not the project.
  • "Custom control … is already installed in this environment by another solution." — the logical name is taken. Rename the control, or remove the other registration.
  • "Environment … is not active." — wait until the environment finishes provisioning, or choose a different environment.

While you are writing the control​

Uploading a package for every change is a slow loop. In a development environment, New offers a second choice, Use a running dev server: type the address npm run dev prints and select Register custom control. The control's name and its federation settings are read from the dev server, and forms load the control from it, so a change you save shows the next time a form opens. The Version column reads Hosted (development) while it is registered this way.

  • If the control is already installed, remove it first. A dev server registers under the control's own logical name, so the form you bound it to keeps using it.
  • When you are done, upload the package. It replaces the dev-server registration, and the Version column shows the build again.

The choice does not appear outside a development environment: a control registered that way has no package, so its code would not travel with the solution. Setting up the control's project for it is in Build a Custom Control.

  • Build a Custom Control.
  • Bind a Custom Control to a field.
  • Register a Custom React App.
  • Create a solution.