Skip to content

init(options)

Returns an app instance with addQuery, addAction, addFormAction, onError, start, and dispose methods.

js
import { init } from "gg-wf-scripts";

const app = init({
  context: { sb },
  auth: { /* see Auth adapter below */ },
  debug: false,
});

Options

OptionTypeRequiredDescription
contextobjectNoArbitrary object passed to every query and action. Put backend clients or anything else your handlers need on it. Defaults to {}.
authobjectNoAuth adapter (see below). If omitted, gg-auth / gg-role attrs are never set.
debugbooleanNoWhen true, every query and action is logged to the console (trigger/container, data, result, duration). Defaults to false.
exposebooleanNoWhen true (default), the app is exposed as window.ggApp and a gg-app-ready CustomEvent is dispatched on document. Set to false for tests, multiple instances, or non-browser hosts.
transitionobjectNoGlobal fade-in/out for every show/hide the library performs. See Transitions below. Omit for instant toggles (default).

Transitions

Every show/hide the library performs — gg-auth / gg-role gating, gg-switch-state cases, gg-visible-when form fields, and freshly-rendered gg-data-list rows — runs through a single visibility helper. By default it's an instant display:none toggle (matching pre-6.0 behavior). Pass a transition to fade them instead.

js
init({
  transition: { duration: 200, easing: "easeInOut" },
});
FieldTypeDescription
durationnumberFade duration in milliseconds. Defaults to 0 (instant).
easingEasingMotion's easing keyword set: "linear", "easeIn", "easeOut", "easeInOut" (default), "circIn" / "circOut" / "circInOut", "backIn" / "backOut" / "backInOut", "anticipate". Or a [x1, y1, x2, y2] cubic-bezier tuple.

The system honors prefers-reduced-motion: reduce — animations are skipped automatically when the OS setting is on, regardless of duration.

Hidden elements also get inert and aria-hidden="true" so they're removed from the tab order and from screen readers — this happens whether or not transition is configured.

Auth adapter

OptionTypeDescription
auth.getUser() => string | null | Promise<string | null>Returns the current user id, or null when signed out. Called once on start.
auth.onChange(cb: (userId: string | null) => void) => voidSubscribe to auth changes. Optional but recommended — without it, gg-auth won't update on sign-in/out.
auth.roleQueryasync (context, userId) => string | nullReturns the user's role string. Called on every auth change. If omitted, gg-role is never set.

See Auth and roles for a full Supabase example.

app.start()

Initializes all engines and starts listening for DOM events. Call this after registering all queries and actions.

js
app.addQuery(/* ... */);
app.addAction(/* ... */);
app.addFormAction(/* ... */);
app.start();

Engines also pick up elements inserted after start() — Webflow IX-driven content, CMS templates, or anything appended at runtime — via a shared MutationObserver. You don't need to re-run start().

app.onError(handler)

Subscribe to handler failures. Fires when:

  • A registered query, action, or form action throws.
  • The DOM references a handler id that wasn't registered.
  • A handler returns { ok: false, error } (or { ok: false, field_errors } for form actions).
js
app.onError(({ prefix, id, error }) => {
  Sentry.captureException(error, { tags: { handler: `${prefix} ${id}` } });
});

The handler receives a GgErrorEvent:

FieldTypeDescription
prefixstringEngine label, e.g. "[gg-action]", "[gg-data]", "[gg-form-action]".
idstringHandler id (the value of the gg-action / gg-data / gg-form-action attribute).
errorunknownThe thrown value, or a string describing the non-throw failure.
fieldsobjectEngine-specific context: trigger element, form, params, data.

Returns an unsubscribe function.

app.dispose()

Detaches every listener and observer the library installed. Call from SPA route changes, HMR teardown, or test cleanup. Handler registrations are kept, so you can call start() again on the same app.

js
const app = init({ context });
app.addQuery(/* ... */);
app.start();

// later, e.g. on route change
app.dispose();

Released under the MIT License.