Quickstart
This gets a working import flow onto your page. You need access to the published packages and a self-hosted (or pilot) engine endpoint with a signed license key.
0. Try it first — no install, no signup
Section titled “0. Try it first — no install, no signup”The playground runs the real widget in your browser: upload a messy file (or use the preloaded samples) and walk upload → match → review → apply in under a minute. If the flow fits, everything below is the same widget pointed at your schema.
1. Install the package
Section titled “1. Install the package”Point npm’s @capitality-io scope at GitHub Packages once, using the token from onboarding:
@capitality-io:registry=https://npm.pkg.github.com//npm.pkg.github.com/:_authToken=${MILDPORT_NPM_TOKEN}npm install @capitality-io/mildport-widget2. Define the custom element
Section titled “2. Define the custom element”import { defineImportSuiteElement } from '@capitality-io/mildport-widget';
await defineImportSuiteElement('mildport-import');3. Drop it in and point it at your schema
Section titled “3. Drop it in and point it at your schema”The recommended default is a server-managed target catalog: the schema lives in Mildport’s no-code editor (drafted from your API spec if you like), versioned with rollback, and schema changes publish without a host release. The embed stays three attributes:
<mildport-import api-base-url="https://imports.your-infra.example" license-key="SIGNED_TENANT_KEY" catalog-key="crm"></mildport-import>const el = document.querySelector('mildport-import')!;el.addEventListener('import-applied', e => sync(e.detail));Alternative: schema-as-code
Section titled “Alternative: schema-as-code”Prefer the schema versioned and type-checked with your app — or need fields computed per
user at runtime? Pass targets from host code instead of catalog-key (derive them from
Zod schemas with @capitality-io/mildport-zod):
import { mountImportFlow } from '@capitality-io/mildport-widget';
const el = document.querySelector('mildport-import')!;
mountImportFlow(el, { id: 'my-import', version: 'v1', targets: [ { id: 'contact', label: 'Contact', fields: [ { key: 'contact.email', label: 'Email', columnType: 'email', required: true }, { key: 'contact.name', label: 'Name' }, ], }, ], input: { acceptedFormats: ['spreadsheet', 'text', 'pdf'] }, delivery: { mode: 'browser' },});
el.addEventListener('import-applied', e => sync(e.detail));No engine yet? Add the offline attribute and drop api-base-url/license-key — the
whole flow (parse, match, review, apply) runs in the browser with the bundled deterministic
matcher, so you can wire and demo the integration before any backend exists:
<mildport-import offline></mildport-import>In browser delivery the rows reach your code through the resultsHook — the third argument
of mountImportFlow — just before apply (import-applied’s detail carries the summary:
recordId, action, rowCount):
mountImportFlow(el, flowInput, { resultsHook: ({ rows, mapping }) => sync(rows),});That’s the whole integration surface: attributes in, DOM events out. No SDK lock-in, no iframe.
- Your first import — catalog, embed, review, signed webhook.
- Target catalogs — manage the schema in the no-code editor, draft it from an API spec, version and roll back.
- Configure the widget —
targets, attributes, apply modes. - Events & apply — the lifecycle events and how rows reach your app.
- Theming — match the widget to your design system.