Custom Modules
The SDK ships with a built-in middlewareModule that covers most use cases — communicating with the Server Middleware. When you need behavior that doesn't involve the middleware at all (a logger, an analytics tracker, a direct third-party API client), you can build a custom module instead.
When is a custom module necessary?
You can customize the built-in module's behavior by extending it. A custom module is only needed when the module communicates with a third-party service directly and shouldn't reach the Server Middleware at all.
Module structure
A module is a factory function that returns an object with three parts:
connector— the module's public methods.utils— helper functions exposed alongside the connector.subscribers— callbacks triggered by SDK events.
Create a new directory sdk/modules/logger, then add a module.ts file:
import { Module } from "@alokai/connect/sdk";
export const loggerModule = () => {
return {
connector: {},
utils: {},
subscribers: {},
} satisfies Module;
};
Connector
The connector holds the module's public methods. Start by adding a simple log method:
import { Module } from "@alokai/connect/sdk";
export const loggerModule = () => {
return {
connector: {
log: (message: string) => {
console.log(message);
},
},
utils: {},
subscribers: {},
} satisfies Module;
};
Extracting the connector
As the module grows, move the connector into its own file to keep things organized:
import { Connector } from "@alokai/connect/sdk";
export const loggerConnector = () => {
return {
log: (message: string) => {
console.log(message);
},
} satisfies Connector;
};
Then import it in the module:
import { Module } from "@alokai/connect/sdk";
import { loggerConnector } from "./connector";
export const loggerModule = () => {
return {
connector: loggerConnector(),
utils: {},
subscribers: {},
} satisfies Module;
};
Methods
For even better separation, extract individual methods into a methods.ts file:
export const log = (message: string) => {
console.log(message);
};
Spread them into the connector:
import { Connector } from "@alokai/connect/sdk";
import * as methods from "./methods";
export const loggerConnector = () => {
return {
...methods,
} satisfies Connector;
};
Methods can contain any logic you need. For example, sending logs to a remote server:
export const log = (message: string) => {
console.log(message);
fetch("https://example.com/log", {
method: "POST",
body: JSON.stringify({ message }),
});
};
Utils
Utils are helper functions exposed alongside the connector. For example, a message formatter that adds a timestamp:
import { Module } from "@alokai/connect/sdk";
import { loggerConnector } from "./connector";
export const loggerModule = () => {
return {
connector: loggerConnector(),
utils: {
formatMessage: (message: string) => {
return `${new Date().toISOString()} - ${message}`;
},
},
subscribers: {},
} satisfies Module;
};
Subscribers
Subscribers react to SDK events. For example, the following subscriber sends a log to the server after every SDK method call across all modules. Learn more in the Subscribers docs.
import { Module } from "@alokai/connect/sdk";
import { loggerConnector } from "./connector";
export const loggerModule = () => {
return {
connector: loggerConnector(),
utils: {
formatMessage: (message: string) => {
return `${new Date().toISOString()} - ${message}`;
},
},
subscribers: {
"*_after": (payload) => {
fetch("https://example.com/log", {
method: "POST",
body: JSON.stringify(payload),
});
},
},
} satisfies Module;
};
Registering the module
Wrap the module with defineSdkModule and export it from the modules directory:
import { defineSdkModule } from "@vue-storefront/next";
import { loggerModule } from "./module";
export const logger = defineSdkModule(({ buildModule }) =>
buildModule(loggerModule)
);
Then export it from sdk/modules/index.ts:
// ... other module exports
export * from "@/sdk/modules/logger";
Usage
Once registered, the module is available through the SDK:
const message = sdk.logger.utils.formatMessage("Hello, World!");
sdk.logger.log(message); // 2021-01-01T00:00:00.000Z - Hello, World!