Custom Middlewares
A middleware is a function that wraps the store’s dispatch pipeline. The signature is the standard Redux-style triple-function:
import type { Middleware, State, Action } from '@golemui/core';
export const myMiddleware: Middleware<State, Action> = (store) => (next) => (action) => { // inspect / branch on `action` and `store.getState()` here return next(action); };Pass it through the middlewares prop of the form component (this stays as a separate prop, not inside formConfig).
Worked example — language analytics
Section titled “Worked example — language analytics”Suppose you want to know which languages your users actually pick. GolemUI dispatches a SET_LANGUAGE action every time the active translator notifies of a language change (see i18n), so a middleware can forward that to your analytics service without touching the form definition.
import type { Middleware, State, Action } from '@golemui/core';import { analytics } from './analytics'; // your analytics SDK
export const languageAnalyticsMiddleware: Middleware<State, Action> = (store) => (next) => (action) => { if (action.type !== 'SET_LANGUAGE') { return next(action); }
const from = store.getState().lang; const result = next(action); const to = action.payload.lang;
if (from !== to) { analytics.track('language_changed', { from, to }); } return result; };Two things worth pointing out:
- The
if (action.type !== 'SET_LANGUAGE') return next(action);early exit keeps the middleware out of the way for every other action — middlewares run on every dispatch, so cheap branching matters. - We capture
frombefore callingnext(action)andtofrom the action payload, so the event always reports the real transition. Readingstore.getState().langafternext(action)would also work, but reading the payload directly is fewer moving parts.
Wire it through the middlewares prop alongside any other middlewares you use:
import { languageAnalyticsMiddleware } from './middlewares/language-analytics';
const middlewares = [languageAnalyticsMiddleware];
// <GuiForm ... middlewares={middlewares} />That’s all — the next time the user switches the language dropdown your analytics dashboard will start logging which languages get picked, with no changes to the form definition itself.
Other patterns
Section titled “Other patterns”- Logging. Log every action and resulting state — useful during development. The built-in
loggerMiddlewarefrom@golemui/coredoes this. - Persistence. Watch
SET_WIDGET_DATAactions and persist the form state tolocalStorage, then rehydrate on next mount. - Telemetry. Same shape as the example above, but track other actions —
'INJECT_VALIDATION_ISSUES'for validation failures,'SET_WIDGET_DATA'for engagement on specific fields, etc.
See also
Section titled “See also”- Features / Middlewares — built-in middlewares and how to wire them.