Skip to content

Build an Extension

An Extension lives in its own repository. A typical repository contains an Extension manifest, a browser entry module, an optional provider backend, and deployment configuration for the provider’s chosen platform.

Use the Typeroll Extension starter as a GitHub template to get a working frontend, local host, provider example, manifest tooling, tests, and CI.

  • Node.js 22 or later;
  • a Typeroll organization and a site where you have admin permission;
  • an organization-scoped API key;
  • HTTPS origins for production assets and provider endpoints.

In Typeroll, open Developer → Extensions, register a lowercase namespaced Extension ID, and copy the client secret when the Extension uses admin SSO. The secret is shown once and must remain server-side.

  1. Add typeroll-extension.json to the repository root.
  2. Implement a browser module that exports mount(element, props, context).
  3. Build the frontend into immutable JavaScript and CSS assets.
  4. Put the exact SHA-256 asset hashes and public HTTPS URLs in the manifest.
  5. Validate and upload a draft.
  6. Install the draft on a development site owned by the same Typeroll organization and approve its requested scopes.
  7. Publish a private or unlisted version, or submit a public version for review.

The @typeroll/mcp-server package includes the typeroll developer CLI:

Terminal window
export TYPEROLL_API_URL="https://your-admin.example.com"
export TYPEROLL_API_KEY="your organization-scoped API key"
npx --package @typeroll/mcp-server typeroll extension validate
npx --package @typeroll/mcp-server typeroll extension push --draft
npx --package @typeroll/mcp-server typeroll extension install --site your-site-id \
--config extension-config.json
npx --package @typeroll/mcp-server typeroll extension configure --site your-site-id \
--installation your-installation-id --config extension-config.json
npx --package @typeroll/mcp-server typeroll extension promote 1.0.0

Local validation is a fast shape check. The portal remains authoritative for schema compatibility, trusted origins, permissions, configuration, and asset hash verification.

extension configure merges the schema-defined values in the JSON file into the current installation config and queues a production deploy by default. Omitted values, including masked secrets, are preserved. Use --no-deploy only when applying several changes, then trigger one deploy after the last update. The installation ID is returned by extension install and is also shown under Settings → Extensions.

Manifest v3 replaces the old gateway transport with a direct api contract. Provider requests must go straight from the browser to the provider backend; do not add a Typeroll relay or a customer Cloudflare Pages Function.

For a backend-free lead tool, first create the receiving form in Typeroll, declare it under the component’s form_bindings, and request forms:submit. The form ID must match on the installation’s site. Its fields and post-submit email or webhook actions remain managed in the ordinary Forms admin.

Draft and review versions can only be installed on sites owned by the Extension’s developer organization. Other organizations can only install a published version. You may change distribution while every saved version is still a draft; Typeroll updates those draft manifests and hashes together. Once any version has been published or submitted for review, distribution is locked.

After installation, the component appears in the editor’s block picker. In HTML mode, use the provisioned block ID displayed under Settings → Extensions:

<x-extension
block="extension--install-abc--quote"
props='{"heading":"Your quote"}'
/>

This is an authoring directive, not a second script runtime. Preview and build replace it with the same inert mount shell used by a visual-editor block.

Published versions are immutable. Never replace asset bytes at a URL while reusing the same version and hashes. Release a new semantic version, upload it, and let Typeroll select it automatically for compatible installations.

An installation is a timeless connection to the Extension ID. Its approved scopes never expand automatically: a new release can declare another scope, but it cannot use that scope until a site administrator grants it separately. Keep component IDs, props, configuration, and provider data backward compatible. Use a new Extension ID for a deliberately breaking product.

If none of the published releases can run with the current runtime and stored configuration, Typeroll marks the Extension unavailable and omits it from the site build. Other pages and Extensions continue to build normally.

Continue with the frontend runtime and recipient-link contract.