Skip to content
Get started

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.

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.

Point npm’s @capitality-io scope at GitHub Packages once, using the token from onboarding:

.npmrc
@capitality-io:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${MILDPORT_NPM_TOKEN}
Terminal window
npm install @capitality-io/mildport-widget
main.ts
import { defineImportSuiteElement } from '@capitality-io/mildport-widget';
await defineImportSuiteElement('mildport-import');

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>
wire-it-up.ts
const el = document.querySelector('mildport-import')!;
el.addEventListener('import-applied', e => sync(e.detail));

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):

wire-it-up.ts
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.