@maestrio/sdk
Official JavaScript/TypeScript SDK for Maestrio — submit bug reports and feature requests from your app.
Installation
npm install @maestrio/sdk
pnpm add @maestrio/sdk
yarn add @maestrio/sdk
CDN (UMD)
<script src="https://unpkg.com/@maestrio/sdk"></script>
<script>
const maestrio = Maestrio.createMaestrio({
apiKey: "mst_...",
baseUrl: "https://app.maestrio.com",
projectId: "your-project-id",
});
</script>
Quick Start
import { createMaestrio } from "@maestrio/sdk";
const maestrio = createMaestrio({
apiKey: "mst_...",
baseUrl: "https://app.maestrio.com",
projectId: "your-project-id",
});
maestrio.identify("user-123", {
name: "Jane Doe",
email: "jane@example.com",
});
const result = await maestrio.submitRequest({
title: "Button doesn't work",
description: "The submit button on the settings page is unresponsive.",
type: "bug",
});
result.match({
ok: (data) => console.log("Request created:", data.id),
err: (error) => console.error("Failed:", error.message),
});
API Reference
createMaestrio(config)
Creates a new Maestrio SDK instance.
const maestrio = createMaestrio({
apiKey: string;
baseUrl: string;
projectId: string;
widget?: WidgetConfig;
});
maestrio.identify(userId, userProperties?, systemProperties?)
Identifies the current user. Must be called before submitRequest() or show().
maestrio.identify(
"user-123",
{ name: "Jane", email: "jane@example.com", avatar: "https://..." },
{ autoShow: true },
);
userId | string | Unique user identifier |
userProperties | UserProperties? | Optional user metadata |
systemProperties | SystemProperties? | Options like autoShow (default false) |
maestrio.submitRequest(params)
Submits a bug report or feature request. Returns a Result (from better-result).
const result = await maestrio.submitRequest({
title: "Add dark mode",
description: "Please add a dark mode toggle to settings.",
type: "feature",
});
Success response:
{ id: string; status: string; queued: boolean }
maestrio.show()
Opens the feedback widget. Requires a prior identify() call.
maestrio.hide()
Closes the feedback widget.
maestrio.destroy()
Removes the widget from the DOM and cleans up all resources.
Widget Customization
Position
Control where the widget appears on screen:
createMaestrio({
apiKey: "mst_...",
baseUrl: "https://app.maestrio.com",
projectId: "your-project-id",
widget: {
position: "right-center-vertical",
},
});
Theme
Override the widget's visual style by passing a theme object. Under the hood, each theme property maps to a CSS custom property on the <maestrio-widget> web component. When you pass a theme value, the SDK calls style.setProperty() on the host element, overriding the built-in defaults.
How it works
The widget renders inside a Shadow DOM, so its styles are fully isolated from your app. All visual tokens are defined as CSS custom properties on the :host element:
:host {
--maestrio-primary: #4a7c59;
--maestrio-primary-foreground: #ffffff;
--maestrio-bg: #ffffff;
--maestrio-text: #1a1a1a;
--maestrio-text-secondary: #6b7280;
--maestrio-border: #e5e7eb;
--maestrio-input-bg: #f5f5f5;
--maestrio-radius: 12px;
--maestrio-font: system-ui, -apple-system, sans-serif;
}
When you provide a theme in the config, each key is mapped to its corresponding CSS variable and applied at runtime:
primaryColor | --maestrio-primary | #4a7c59 | Buttons, accents, focus rings, selected states |
primaryForeground | --maestrio-primary-foreground | #ffffff | Text/icon color on primary elements |
backgroundColor | --maestrio-bg | #ffffff | Modal panel background |
textColor | --maestrio-text | #1a1a1a | Headings, labels, body text |
borderRadius | --maestrio-radius | 12px | Modal corners, buttons, inputs (derived via calc) |
Usage
createMaestrio({
widget: {
theme: {
primaryColor: "#6366f1",
primaryForeground: "#ffffff",
backgroundColor: "#1e1e2e",
textColor: "#cdd6f4",
borderRadius: "12px",
},
},
});
All theme properties are optional — only the values you provide will override the defaults.
Derived values
Some internal CSS variables are not directly configurable through the theme object but are derived from the tokens above:
--maestrio-text-secondary (#6b7280) — used for descriptions and placeholders
--maestrio-border (#e5e7eb) — used for card borders, input borders, dividers
--maestrio-input-bg (#f5f5f5) — used for textarea and card backgrounds
--maestrio-font (system-ui, -apple-system, sans-serif) — widget font stack
Border radius is automatically scaled down for inner elements (buttons, inputs, cards) using calc(var(--maestrio-radius) - 2px) and calc(var(--maestrio-radius) - 4px), so changing borderRadius keeps proportions consistent across the entire widget.
Labels
Override any user-facing text in the widget. All label properties are optional — defaults are used for any you don't provide.
createMaestrio({
widget: {
labels: {
triggerText: "Feedback",
headerText: "Send us feedback",
bugLabel: "Report a Bug",
bugDescription: "Something isn't working as expected",
suggestionLabel: "Suggestion",
suggestionDescription: "Got an idea? We'd love to hear it.",
bugPlaceholder: "Describe the problem and when it happened...",
suggestionPlaceholder: "Describe what you'd like to see...",
bugTextareaLabel: "What went wrong?",
suggestionTextareaLabel: "What would you like to see?",
sendButton: "Send",
cancelButton: "Cancel",
},
},
});
triggerText | "Feedback" | Floating trigger button text |
headerText | "What is your feedback?" | Modal title |
bugLabel | "Bug" | Bug card heading |
bugDescription | "Found a problem? Let us know." | Bug card subtext |
suggestionLabel | "Suggestion" | Feature card heading |
suggestionDescription | "Got an idea? We'd love to hear it." | Feature card subtext |
bugPlaceholder | "Describe the problem and when it happened..." | Textarea placeholder for bugs |
suggestionPlaceholder | "Describe what you'd like to see..." | Textarea placeholder for features |
bugTextareaLabel | "What went wrong?" | Textarea label for bugs |
suggestionTextareaLabel | "What would you like to see?" | Textarea label for features |
sendButton | "Send" | Submit button text |
cancelButton | "Cancel" | Cancel button text |
Full Example
const maestrio = createMaestrio({
apiKey: "mst_...",
baseUrl: "https://app.maestrio.com",
projectId: "your-project-id",
widget: {
position: "right-center-vertical",
theme: {
primaryColor: "#6366f1",
primaryForeground: "#ffffff",
backgroundColor: "#ffffff",
textColor: "#1f2937",
borderRadius: "8px",
},
labels: {
triggerText: "Help & Feedback",
headerText: "How can we help?",
},
},
});
Error Handling
The SDK uses the Result pattern instead of throwing errors.
import { NotIdentifiedError, ApiError, NetworkError, ValidationError } from "@maestrio/sdk";
const result = await maestrio.submitRequest({ ... });
result.match({
ok: (data) => {
console.log("Created:", data.id);
},
err: (error) => {
switch (error._tag) {
case "NotIdentifiedError":
console.error("Call identify() first");
break;
case "ApiError":
console.error(`API error ${error.status}: ${error.message}`);
break;
case "NetworkError":
console.error("Network failed:", error.message);
break;
case "ValidationError":
console.error(`Invalid ${error.field}: ${error.message}`);
break;
}
},
});
TypeScript Types
All types are exported for use in your application:
import type {
MaestrioConfig,
MaestrioSDK,
UserProperties,
SystemProperties,
RequestType,
SubmitRequestParams,
SubmitRequestResponse,
SdkError,
} from "@maestrio/sdk";