Skip to content

zooza-dev/zooza-widgets-module

Repository files navigation

Zooza Widgets

Embed Zooza widgets (registration, calendar, profile, video, checkout, map) in any web app — as npm packages instead of copy-paste <script> snippets.

All packages are thin adapters around one core loader that reproduces the official embed mechanism exactly, and add what the snippets lack: unique ids (multiple widgets per page), clean unmount, SSR safety, TypeScript types and a Zooza-branded loading placeholder.

Packages

Package For Usage
@zooza/widgets-core Vanilla JS / any framework loadWidget({ type, container })
@zooza/widgets-wc Plain HTML, WordPress, Angular, anything <zooza-widget type="calendar">
@zooza/widgets-react React, Next.js (App Router ready) <ZoozaWidget type="registration" />
@zooza/widgets-vue Vue 3, Nuxt <ZoozaWidget type="checkout" />
@zooza/widgets-svelte Svelte 3/4/5, SvelteKit <div use:zoozaWidget={{ type: 'map' }} />

Angular & Qwik: use @zooza/widgets-wc (custom elements work natively in both); dedicated wrappers are planned.

Setup — API key & region

Every widget needs your company API key (the id value from your Zooza embed snippet, e.g. test123). The key is a public identifier — it ships in the page HTML to every visitor — so keeping it in NEXT_PUBLIC_* / VITE_* env vars is configuration hygiene, not security. Never put real secrets in widget config.

Set it once at app startup — initZooza is re-exported by every package:

import { initZooza } from '@zooza/widgets-react'; // or -vue, -svelte, -wc, -core

initZooza({
  apiKey: import.meta.env.VITE_ZOOZA_API_KEY,   // Next.js: process.env.NEXT_PUBLIC_ZOOZA_API_KEY
  region: 'uk',                                  // optional — omit for the default region
});

Every widget on the page then works without per-widget config. Per-widget props/attributes override the global config when needed (e.g. multi-tenant admin previews).

Regions resolve to https://{region}.api.zooza.appuk, asia today, any future region string works without a package update. Omit (or 'default') for https://api.zooza.app. apiUrl is a full override that beats region. Note: the API base is page-global (a <body> attribute in the embed contract) — one region per page.

Quick start

React / Next.js

npm install @zooza/widgets-react
import { ZoozaWidget } from '@zooza/widgets-react';

export default function BookingPage() {
  return <ZoozaWidget type="registration" />;
}

Vue 3

npm install @zooza/widgets-vue
<script setup>
import { ZoozaWidget } from '@zooza/widgets-vue';
</script>

<template>
  <ZoozaWidget type="calendar" />
</template>

Svelte

npm install @zooza/widgets-svelte
<script>
  import { zoozaWidget } from '@zooza/widgets-svelte';
</script>

<div use:zoozaWidget={{ type: 'checkout' }}></div>

Plain HTML / any other framework

<script src="https://unpkg.com/@zooza/widgets-wc"></script>
<script>ZoozaWidgets.initZooza({ apiKey: 'test123' });</script>

<zooza-widget type="registration"></zooza-widget>

Or as a module:

npm install @zooza/widgets-wc
import '@zooza/widgets-wc/register';

Vanilla JS (full control)

npm install @zooza/widgets-core
import { initZooza, loadWidget } from '@zooza/widgets-core';

initZooza({ apiKey: 'test123' });

const handle = loadWidget({
  type: 'calendar',
  container: document.querySelector('#booking'),
});

// later
handle.destroy();

Widget types

type Default version
registration v1
profile v1
calendar v2
video v2
checkout v2
map v2

Common options (prop / attribute names vary slightly per framework — see package READMEs):

Option Default Description
type — (required) Widget to embed
apiKey from initZooza Company API key (public) — required here or via init
version per-type (table above) Widget API version override
region from initZooza, else default API region: uk, asia, … → https://{region}.api.zooza.app
apiUrl region-derived Full API base URL override (beats region)
widgetId zooza data-widget-id value (constant, leave alone)
ref location.href Referrer URL reported to the widget API
placeholder true Zooza-branded loading placeholder
onLoad / onError Script lifecycle callbacks

How it works

The packages reproduce the official Zooza embed snippet 1:1:

  1. set data-zooza-api-url on <body>,
  2. insert an embedder <script> whose id is your company API key, plus data-version and data-widget-id attributes,
  3. insert the async widget script {apiUrl}/widgets/{version}/?type={type}&ref={ref} before the embedder.

The remote script identifies your company by reading the embedder's id from the DOM (the key is never in the script URL), then renders the actual widget UI — these packages never reimplement it.

Development

pnpm install
pnpm build          # builds all @zooza/* packages

Examples live in examples/ — vanilla HTML, React + Vite, Next.js, Vue + Vite, Svelte + Vite. Run any of them with pnpm --filter example-react-vite dev (after pnpm build).

Releasing

pnpm changeset          # describe the change
pnpm version-packages   # bump versions
pnpm release            # build + publish all packages

All @zooza/* packages are version-linked and published with public access.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors