Skip to Content
v1.33.8 · shipped One-screen report · Looks like your app Read the changelog →
SDK reference@mushi-mushi/core

@mushi-mushi/core

Shared types, HTTP client, offline queue helpers, and config used by every Mushi Mushi framework SDK. It is framework-agnostic, and you rarely install it directly.

Install

pnpm add @mushi-mushi/core

Every SDK needs a project ID and an API key. Create a free account  (no card) and create a project to get both; Project ID & API keys explains each one.

API

Mushi.init(config) (web) / MushiProvider (React Native)

interface MushiConfig { projectId: string // UUID from the console Projects page apiKey: string // report:write key — shown once at project creation apiEndpoint?: string // override for self-hosted deployments /** Automatic error reports only (0–1). User feedback always sends. Default 1. */ sampleRate?: number /** Session-replay sampling (0–1). Decision at init. Default 1. */ replaySampleRate?: number /** Drop or mutate any report after PII scrub. Prefer over beforeSendFeedback. */ beforeSend?: (report: MushiReport) => MushiReport | null | Promise<MushiReport | null> }

Get both values in one step by running mushi login or by creating a project in the Mushi Mushi console . The ID and key are shown together on the success screen after project creation.

Sampling + beforeSend examples: @mushi-mushi/web.

MushiWidgetConfig (selected keys)

interface MushiWidgetConfig { position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' theme?: 'auto' | 'light' | 'dark' | 'inherit' trigger?: 'auto' | 'banner' | 'edge-tab' | 'attach' | 'manual' | 'hidden' /** 1.19+ — privacy caption under screenshot preview */ screenshotSensitiveHint?: boolean | string }

See docs/SDK_SCREENSHOT_PREVIEW.md for the full preview + consent flow.

captureEvent(input)

Send a report from code through the SDK instance (Mushi.getInstance() on web). The input is MushiCaptureEventInput:

interface MushiCaptureEventInput { description: string category?: 'bug' | 'slow' | 'visual' | 'confusing' | 'other' severity?: 'critical' | 'high' | 'medium' | 'low' component?: string tags?: Record<string, string | number | boolean> source?: string error?: { name?: string; message?: string; stack?: string } metadata?: Record<string, unknown> }

The full wire shape the SDKs build for you is MushiReport (environment, console and network logs, screenshotDataUrl, reporter token, and more).

Offline queue

createOfflineQueue() is the IndexedDB queue the web SDK uses. Queued reports send automatically when the connection returns; there is no manual flush call to make.

PII scrubbing utilities (1.27+)

The redactor that every SDK uses at capture time is exported so you can reuse it in your own beforeSend hook, server code, or logs. It runs entirely in your process, so scrubbed values never leave the client.

import { scrubPii, scrubUrl, createPiiScrubber } from '@mushi-mushi/core' // Free text → typed placeholders scrubPii('email jake@x.com or call +1 415 555 0100') // → 'email [REDACTED_EMAIL] or call [REDACTED_PHONE]' // URL query values → redacted; keys and path preserved for debuggability scrubUrl('/articles?tag=dragons&token=eyJhbGciOiJIUzI1NiJ9.payload.sig') // → '/articles?tag=dragons&token=[Scrubbed]'

scrubPii(text, config?) replaces sensitive substrings anywhere in free text. scrubUrl(url, config?) redacts only query-string values (both the standard ?… part and any ?… inside a hash-router fragment, #/path?…) and leaves keys and path segments intact. scrubUrl redacts values under known-sensitive keys (any key containing token, jwt, passw, pwd, secret, api_key/apikey, auth, session, signature, email, phone or ssn, case-insensitive, plus the exact keys key / code / sig) to [Scrubbed], then pattern-scrubs the remaining values so a JWT hiding under an innocent key (?next=eyJ…) is still caught. Both accept absolute or relative URLs and never throw.

Patterns and their placeholders (all matched case-sensitively unless noted):

DataPlaceholderDefault
Email[REDACTED_EMAIL]on
Phone number[REDACTED_PHONE]on
US SSN[REDACTED_SSN]on
Credit-card PAN[REDACTED_CC]on
JWT (eyJ….….…)[REDACTED_JWT]on
AWS access key[REDACTED_AWS_KEY]on
AWS secret access key (case-insensitive key name)aws_secret_access_key=[REDACTED_AWS_SECRET]on
Stripe secret / restricted key[REDACTED_STRIPE_KEY]on
Stripe publishable key[REDACTED_STRIPE_PK]on
Slack token[REDACTED_SLACK_TOKEN]on
GitHub personal access token[REDACTED_GITHUB_PAT]on
OpenAI key[REDACTED_OPENAI_KEY]on
Anthropic key[REDACTED_ANTHROPIC_KEY]on
Google API key[REDACTED_GOOGLE_KEY]on
IPv4 address[REDACTED_IP]off
IPv6 address[REDACTED_IPV6]off

IP scrubbing is off by default because IPs are frequently load-bearing for debugging (rate-limit keys, geo). Toggle any pattern via PiiScrubberConfig:

interface PiiScrubberConfig { emails?: boolean // default true phones?: boolean // default true creditCards?: boolean // default true ssns?: boolean // default true secretTokens?: boolean // default true — JWTs + vendor API keys ipAddresses?: boolean // default false — IPv4 ipv6?: boolean // default false } // e.g. also redact IPs, keep everything else on scrubPii(text, { ipAddresses: true })

createPiiScrubber(config) returns { scrub, scrubObject } when you want to build the scrubber once and reuse it across many strings or object fields:

const { scrub, scrubObject } = createPiiScrubber({ ipAddresses: true }) scrub(logLine) scrubObject(record, ['description', 'url']) // scrubs only those string keys

The pattern set is the single source of truth shared with the Flutter SDK’s generated copy, so the two scrubbers can’t drift.

Region resolution

import { resolveRegionEndpoint, REGION_ENDPOINTS } from '@mushi-mushi/core' const url = await resolveRegionEndpoint({ projectId: 'YOUR_PROJECT_ID', apiEndpoint: REGION_ENDPOINTS.us, region: 'eu', })

REGION_ENDPOINTS contains the canonical URLs:

const REGION_ENDPOINTS = { us: 'https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api', eu: 'https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api', jp: 'https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api', }
Last updated on