@scriptiflow/sdk
v0.3.0
Published
Embeddable car-inventory search, detail views and lead capture for dealership websites — themeable web components plus a typed headless client for the Scriptiflow platform.
Maintainers
Readme
@scriptiflow/sdk
Put your Scriptiflow-managed car inventory on any website. Drop two tags into the page and get a complete, themeable car-search experience — filters, cards with photo carousels, a full detail view, and a lead form that feeds your Scriptiflow CRM.
A single publishable API key (sf_pk_live_…, issued by Scriptiflow for your
brand) identifies the embed. The key is public by design — security comes from
the server-side origin allowlist, per-key rate limits, and instant revocation.
Quick start
<link rel="stylesheet" href="https://unpkg.com/@scriptiflow/sdk@^0/dist/scriptiflow.min.css" />
<script src="https://unpkg.com/@scriptiflow/sdk@^0/dist/scriptiflow.min.js"></script>
<scriptiflow-root api-key="sf_pk_live_…">
<scriptiflow-inventory page-size="24">
<div class="scriptiflow-shell">
<scriptiflow-filters></scriptiflow-filters>
<scriptiflow-count></scriptiflow-count>
<scriptiflow-sort label="Sort"></scriptiflow-sort>
<scriptiflow-grid></scriptiflow-grid>
<scriptiflow-pagination></scriptiflow-pagination>
</div>
<scriptiflow-details></scriptiflow-details>
</scriptiflow-inventory>
</scriptiflow-root>That's the whole integration. Pin the CSS and JS to the same version
specifier. Also available via jsDelivr:
https://cdn.jsdelivr.net/npm/@scriptiflow/sdk@^0/dist/….
What's in the package
- Web components (CDN bundle,
dist/) — self-registering<scriptiflow-*>custom elements. Light DOM, no shadow roots, themeable with CSS variables, responsive to the embed's width via container queries. The bundle also exposes the globalScriptiflow. - Headless JS client (
esm/, whatnpm installgives you) — small, typedSdk/Inventory/Leadsclasses for fully custom integrations.
Components
| Tag | Purpose |
| --- | --- |
| scriptiflow-root | Context owner: api-key (required), api-url, data-theme, source (catalog | inventory; omitted → auto-detected from the key) |
| scriptiflow-inventory | State owner. One-shot seeds: filter-q/-make/-model/-fuel/-gearbox/-body/-price-min/-price-max/-year-min/-year-max/-km-max, sort, page-size (max 100), statuses (comma union of active/sold/new), listing-href ({id} {make} {model} placeholders), listing-target |
| scriptiflow-filters | Bundled filter toolbar (search, make → model, price, year, "More" panel, reset, loading) with an applied-filters chip row. hide-*, *-label, *-options, search-placeholder, show-status |
| scriptiflow-filter-search/-make/-model/-price/-year/-status/-mileage/-fuel/-gearbox/-body/-reset/-loading | The same filters as individually composable tags for custom layouts (label, options as "Label\|value,…", disabled) |
| scriptiflow-grid / scriptiflow-list | Card grid (columns) / flat list. Card media is a lazy photo carousel — arrows on hover, swipe on touch; extra photos load only when the visitor navigates |
| scriptiflow-card | A single car anywhere: id (fetch) or listing (JSON) |
| scriptiflow-sort / scriptiflow-count / scriptiflow-pagination | Sort select, result count, numbered pager. Default sort is "Recommended" — the order you arranged in Scriptiflow (catalog) or newest first (inventory) |
| scriptiflow-load-more | "Show more cars" button that appends pages — use it instead of scriptiflow-pagination |
| scriptiflow-details | Full detail view in a modal: gallery, key-facts band, equipment checklist, description, grouped specs, sticky price + inquiry panel. Deep-links as ?car=<id> |
| scriptiflow-lead-form | Standalone inquiry form (listing-id, submit-label, success-message). Submissions made offline are queued and sent automatically |
Cars flagged as new arrivals get a New badge automatically; sold cars a
Sold badge (sold stock only appears when you opt in via statuses or the
status filter).
Events (plain CustomEvents on window): scriptiflow-inventory:fetched,
scriptiflow-filters:change, scriptiflow-pagination:change,
scriptiflow-card:click, scriptiflow-details:open,
scriptiflow-lead:submitted, scriptiflow-error.
Theming
Every visual token derives from --sf-* CSS variables (two master knobs:
--sf-scaling, --sf-radius-factor). A brand theme is one CSS block on your
own site:
[data-theme='acme'] {
--sf-accent-9: #c00;
--sf-radius-factor: 0.8;
}<scriptiflow-root api-key="…" data-theme="acme">A built-in compact theme ships. Layout reflows by embed width, so a
narrow sidebar placement gets the mobile layout even on a desktop page.
Custom card templates
Agencies can replace the built-in card markup entirely — no build tooling:
<scriptiflow-grid>
<template sf-each>
<article class="my-card" sf-details>
<img src="{{ car.image }}" alt="" />
<h3>{{ car.make }} {{ car.model }} <small>{{ car.generation }}</small></h3>
<p><span data-format="km">{{ car.mileage_km }}</span> ·
<span data-format="enum">{{ car.fuel }}</span></p>
<strong>{{ car.price_display }}</strong>
</article>
</template>
<template sf-state="empty"><p>No cars right now — call us!</p></template>
</scriptiflow-grid>Bindings are dotted paths only, HTML in data always renders as text, scripts
and event-handler attributes are rejected, and updates are keyed so images
never reflash. The full template, token, and layout reference (docs/agencies.md)
ships in the source repository — ask your Scriptiflow contact for a copy if
you don't have repo access.
Headless usage
npm install @scriptiflow/sdkimport { Sdk } from '@scriptiflow/sdk'
const sdk = new Sdk({ api_key: 'sf_pk_live_…' })
const { data, info } = await sdk.Inventory.search({
filters: { make: 'BMW', price_to: 30000 },
sort: 'price_asc',
page: 1,
limit: 24,
})
const car = await sdk.Inventory.get(data[0].id) // rich detail shape
const facets = await sdk.Inventory.facets({ make: 'BMW' })
await sdk.Leads.capture({ email: '[email protected]', listing_id: car.id })The same classes are available on the CDN bundle as Scriptiflow.Sdk.
Leads.form(element, events) binds any HTML form; sf_campaign /
sf_source / sf_medium URL parameters are attached to leads automatically.
HTTP errors throw a typed ApiError (status, retryAfter). Display
helpers formatEnum, formatFeature, formatConsumption, formatCo2
turn provider values (AUTOMATIC_GEAR, navigationSystem) into human text.
Two data sources, one API: source: 'inventory' (the dealer's own cars,
default) or source: 'catalog' (the brand's curated import-catalog
selection). Filters, sort, and pagination are identical; response envelopes
are normalized. Web components auto-detect the right source from the key.
Free-text q and the status filter are inventory-only and automatically
omitted in catalog mode.
Versioning
| Specifier | Meaning |
| --- | --- |
| @scriptiflow/sdk@^0 | Latest release in the current major (recommended) |
| @scriptiflow/[email protected] | Exact version, never changes |
Use the same specifier for the stylesheet and the script.
Browser support
Modern evergreen browsers. The web components rely on CSS container queries:
Chrome/Edge 105+, Safari 16+, Firefox 110+. The headless client only needs
fetch + ES2017.
License
ISC © Scriptiflow
