@zenky/integrations-sdk
v0.1.3
Published
Framework-agnostic browser SDK for Zenky website integrations.
Downloads
663
Maintainers
Readme
@zenky/integrations-sdk
Framework-agnostic browser SDK for loading Zenky website integrations in eCommerce storefront templates.
The SDK is designed for websites built with Nuxt, Next.js, Vue, Angular, plain JavaScript, or any other frontend stack. Website templates publish normalized Zenky events, integration files register initializers, and the SDK loads assets, passes settings, dispatches events, and collects analytics/attribution data.
Installation
npm install @zenky/integrations-sdkQuick Start
import { createZenkyIntegrationsSDK } from '@zenky/integrations-sdk';
const sdk = createZenkyIntegrationsSDK({
integrations: profile.website.integrations,
debug: true,
});
await sdk.start();
sdk.onProductQuantityIncreased((product) => {
console.log('Product quantity increased', product);
});
sdk.emit('products.someOtherEvent', {
productId: 123,
});
const analyticsData = await sdk.analytics.getAll();
await checkoutApi.createOrder({
...payload,
analytics_data: analyticsData,
});Custom Asset Injection
By default the SDK injects integration JS/CSS files directly into the DOM. Website templates can provide assetInjector when they need to use a framework-level mechanism such as unhead, collect performance timings, or keep script/style injection visible in template-owned code.
Custom injectors receive only asset metadata and completion callbacks. The SDK does not create script/link elements when assetInjector is configured.
const sdk = createZenkyIntegrationsSDK({
integrations: profile.website.integrations,
assetInjector(asset) {
if (asset.language === 'js') {
const script = document.createElement('script');
script.src = asset.url;
script.async = false;
if (asset.integrity) {
script.integrity = asset.integrity;
script.crossOrigin = 'anonymous';
}
script.onload = asset.finish;
script.onerror = () => asset.fail();
document.head.appendChild(script);
return;
}
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = asset.url;
if (asset.integrity) {
link.integrity = asset.integrity;
link.crossOrigin = 'anonymous';
}
link.onload = asset.finish;
link.onerror = () => asset.fail();
document.head.appendChild(link);
},
});Analytics Persistence
By default sdk.analytics stores data in memory only. Website templates can provide analyticsPersistence to persist accepted setField() writes and hydrate getAll() from template-owned storage.
Both callbacks are required when analyticsPersistence is provided, and both are async. sdk.analytics.getAll() waits for queued setField() persistence writes before it calls the persistence getter.
const sdk = createZenkyIntegrationsSDK({
integrations: profile.website.integrations,
analyticsPersistence: {
async setField(payload) {
// { integration_id, field, value }
await persistAnalyticsField(payload);
},
async getAll() {
// Return one record or an array of records:
// { integration_id, fields: { field: value } }
return await readPersistedAnalytics();
},
},
});sdk.analytics.getAll() returns flat analytics field records after reading persisted records and merging current in-memory values:
[
{
"integration_id": "a1e32200-8d2d-427d-88e9-d8760938302e",
"field": "clientId",
"value": "abc-123"
}
]Browser Global
The package creates this browser global when imported or loaded by script:
window.ZenkyIntegrationsSDKGlobal build usage:
<script src="./dist/index.global.iife.js"></script>
<script>
const sdk = window.ZenkyIntegrationsSDK.create({
integrations,
debug: true,
});
await sdk.start();
</script>Integration Script Example
(function () {
window.ZenkyIntegrationsSDK.register(
'a1e32200-8d2d-427d-88e9-d8760938302e',
async function init(settings, sdk, integration) {
const counterId = settings.counter.counter_id;
sdk.onPageViewed(function (page) {
console.log('Send page view', page.url);
}, { replayLatest: true });
sdk.onProductAddedToCart(function ({ order, orderVariant }) {
console.log('Send product added to cart goal', {
order,
orderVariant,
});
});
await sdk.analytics.setField(integration.id, 'clientId', 'demo-client-id');
await sdk.analytics.setField(integration.id, 'counterId', counterId);
}
);
})();API Integration Shape
type ZenkyIntegration = {
id: string;
installation_id: string;
files: ZenkyIntegrationFile[];
settings: Record<string, unknown>;
};
type ZenkyIntegrationFile = {
language: 'js' | 'css';
url: string;
integrity?: string;
};Integration scripts register by integration.id. The full integration object, including installation_id, is passed to the initializer.
API Reference
See DOCS.md for the public API, event helper methods, global methods, analytics methods, and exported utility classes.
Plain HTML Example
The demo in examples/plain-html loads the global build, creates an SDK instance, injects a local demo integration script, emits events, and prints collected analytics data.
Build first:
npm run buildThen serve or open examples/plain-html/index.html. The demo is intentionally self-contained and can be opened through file:// after the build exists.
Package Scripts
npm run typecheck
npm run test
npm run buildLicense
MIT. See LICENSE.md.
