Skip to main content

Embedded Runtime Provider -- Public API Reference

Public API surface of @picsart/runtime/providers/react/embedded.

Entry point: src/providers/react/embedded/index.ts

Overview​

The embedded runtime provider ships a miniapp as a standalone SPA. Runtime and miniapp code are co-bundled, deployed together, and boot synchronously -- no manifest fetch, no iframe, no async loading.

All adapter configuration (auth, pulse, intl, design system, monetization, cookie consent) is autoconfigured internally. The consumer provides only miniapp identity, a starter function, and optional overrides.

Quick Start​

import {
EmbeddedRuntimeProvider,
useEmbeddedRuntimeState,
} from '@picsart/runtime/providers/react/embedded';
import { starter } from './my-miniapp-starter';

const App = () => (
<EmbeddedRuntimeProvider
miniapp={{ packageId: 'com.picsart.my-miniapp', appVersion: '1.0.0' }}
starter={starter}
pulseApp="my-standalone-app"
defaultContext={{ theme: 'dark', language: 'en' }}
>
<StatusIndicator />
</EmbeddedRuntimeProvider>
);

const StatusIndicator = () => {
const state = useEmbeddedRuntimeState();
if (state.isLoading) return <div>Loading...</div>;
if (state.error) return <div>Error: {state.error.message}</div>;
return null;
};

Exports​

Components​

ExportKind
EmbeddedRuntimeProviderReact component

Hooks​

ExportReturns
useEmbeddedRuntimeStateIRuntimePublicState
useEmbeddedHostControlsIEmbeddedHostControls

Types​

ExportKind
IEmbeddedRuntimeProviderPropsComponent props
IEmbeddedMiniappDescriptorMiniapp identity
EmbeddedTemplateTemplate union
ICustomEventPayloadCustom event shape
IRedirectToPackageIdParamsRe-export from SDK
ModuleFactoryRe-export from SDK
IEmbeddedHostControlsHost control methods (3 setters)
IRuntimePublicStateState shape

Component: EmbeddedRuntimeProvider​

Single React component that wraps FullRuntimeProviders + the SDK's EmbeddedMiniapp into a synchronous co-bundled host.

Props (8 total)​

PropTypeRequiredDefaultDescription
miniappIEmbeddedMiniappDescriptoryes--Miniapp identity (packageId, appVersion). Padded into full IMiniapp internally.
starterModuleFactoryyes--The miniapp's bundled starter function. Co-bundled at build time.
pulseAppstringno"picsart.com"Host identifier used in analytics headers and Pulse tracking.
renderingEngineIRenderingEnginenoheadlessRendering engine adapter. Web-layering only imported when explicitly provided.
defaultContextPartial<IRuntimePublicState["context"]>no--Initial context values. Accepts theme, language, sharedStorage, user, credits, subscription, headers. Host-provided headers are merged with runtime auth headers (runtime wins).
templateEmbeddedTemplateno--Host-level page template. "landing" or "create". Enables HTML attribute bridge.
gtmImplementationboolean | stringnotrueThe miniapp's GTM declaration. true starts Picsart's shared container, a container id ("GTM-XXXX") starts only that container, false starts no GTM. A string that is not a container id starts none.
onCustomEvent(payload: ICustomEventPayload) => unknownno--Callback for custom events the runtime does not handle internally.
onRedirectToPackageId(params: IRedirectToPackageIdParams) => voidnoURL navigationOverride for miniapp-to-miniapp redirect. Default navigates to https://{host}/apps?mapp={packageId}&version={appVersion}&experience={experience}.
childrenReactNodeno--Host UI rendered alongside the embedded miniapp.

Autoconfigured Internally (not exposed as props)​

AdapterConfiguration
intlLanguage from defaultContext.language, auth headers from internal auth service
authenticationdisableGoogleInit: true, disableRefreshCycle: true, isDark synced from theme
pulse{ app: pulseApp }
designSystemSensible defaults
monetizationAlways enabled (built-in path, env var defaults). Loaded through a dynamic import, never in the host's startup bundle: with a template the stack sits above the tree and loads before the first render (the template header reads its provider); without one, monetizationLoad decides: "on-mount" (default) keeps it above the tree for host UI in children that reads its provider; "on-demand" mounts it beside the tree once a session exists or a checkout is requested, so visitors who never sign in or buy never download @picsart/monetization or Stripe. The credits-low nudge (CreditsLowNudge from @picsart/monetization) is mounted by default with source: pulseApp; creditsLowNudge={false} leaves it out, an object positions it (top, right, zIndex) or observes it (onOpen, onAction)
cookieConsentUses miniapp.packageId as GTM module ID; the container comes from the gtmImplementation prop (Picsart's shared container by default)
noNetworkAlways enabled, status exposed via IRuntimePublicState.noNetwork
permissionsAll read+write (backend permissions API pending)
fetchOverrideAlways on when REACT_APP_X_APP_AUTHORIZATION_TOKEN is set
errorReportingErrors reported to Bugsnag via growth-rc's errorLogger.trigger()

Hook: useEmbeddedRuntimeState​

const state: IRuntimePublicState = useEmbeddedRuntimeState();

Returns the current IRuntimePublicState from the enclosing EmbeddedRuntimeProvider. Uses useSyncExternalStore internally -- re-renders on every state field change.

Throws when called outside EmbeddedRuntimeProvider.

Return Shape: IRuntimePublicState​

FieldTypeDescription
isLoadingbooleanWhether the miniapp is currently being loaded. Starts true.
isBootstrappedbooleanWhether at least one miniapp has successfully bootstrapped.
errorError | nullThe most recent error from load/bootstrap, or null.
noNetworkbooleanWhether the device is offline. Initialized from navigator.onLine.
context.themestringCurrent theme. Defaults to defaultContext.theme or "light".
context.languagestringCurrent language code. Defaults to defaultContext.language or "en".
context.userIContextUser | nullCurrent user identity. null when unauthenticated.
context.creditsICreditsState | nullCurrent credits balance. null until fetched.
context.subscriptionIUserSubscription | nullCurrent subscription details. null until fetched.
context.sharedStoragestringCurrent shared storage value. Defaults to "".
context.headersRecord<string, string>Merged headers: host-provided defaults + runtime auth headers (runtime wins). Defaults to {}.

Hook: useEmbeddedHostControls​

const controls: IEmbeddedHostControls = useEmbeddedHostControls();

Returns host-side control methods for mutating the embedded runtime's context store. All setter signatures use SDK types from @picsart/miniapp-sdk-types (matching ITransferContext).

Throws when called outside EmbeddedRuntimeProvider.

Return Shape: IEmbeddedHostControls (3 setters)​

MethodSignature
setTheme(theme: Theme) => void
setLanguage(language: LanguageCodes) => void
setSharedStorage(storage: string) => void

Every setter writes to the public state store via context module lenses. Changes propagate to miniapp observers and are readable via useEmbeddedRuntimeState().

Runtime-managed fields (user, credits, subscription, headers, location, settings) are not exposed as host controls — they flow from service providers or are handled internally. Headers can be enhanced via defaultContext.headers on EmbeddedRuntimeProvider.


Types​

IEmbeddedMiniappDescriptor​

interface IEmbeddedMiniappDescriptor {
packageId: string; // Unique package identifier
appVersion: string; // Semantic version string
}

name is omitted -- it is a dead field in embedded mode (SDK never reads it). buildMiniappDescriptor pads name with packageId.

EmbeddedTemplate​

type EmbeddedTemplate = "landing" | "create";

ICustomEventPayload​

interface ICustomEventPayload {
event: string;
data?: Record<string, unknown>;
screen?: string;
}

IRedirectToPackageIdParams​

Re-exported from @picsart/miniapps-platform-sdk/types. Fields: packageId, miniapp (full IMiniapp), redirectionURI.

ModuleFactory​

Re-exported from @picsart/miniapps-platform-sdk/utils/loadRemote/types. The function type returned by a miniapp's bundled entry point.


Internal Behavior​

Fetch Override (always on)​

When REACT_APP_X_APP_AUTHORIZATION_TOKEN is set, a global fetch interceptor injects x-app-authorization, Authorization (from auth service), x-touchpoint (packageId), and platform: "website". Only requests to api.picsart.com and api-stage.picsartstage2.com are intercepted.

Error Reporting (Bugsnag)​

Errors from miniapp loading and bootstrap are reported via errorLogger.trigger() from @picsart/growth-rc/services/errorLogger. React render errors are caught by ErrorBoundaryWrapper.

Redirect (URL navigation)​

When a miniapp calls redirectToPackageId, the default handler navigates to https://{host}/apps?mapp={packageId}&version={appVersion}&experience={experience}. Host detects production vs staging from window.location.hostname. The onRedirectToPackageId prop can override this for custom handling.

Custom Event Routing​

Three events are handled internally:

Miniapp EventAction
OpenRegistrationScreenshowLogin() from LoginModalContext
OpenOfferScreenopenCheckout(options) from MonetizationModalContext
OpenCreditsInfoopenCheckout(options) from MonetizationModalContext

Unknown events are forwarded to onCustomEvent.

HTML Attribute Bridge (template mode only)​

Two-way sync between DOM attributes and context stores. DOM to runtime via MutationObserver on <html class> and <html dir>. Runtime to DOM via store subscription updating classList and RC's setLocale.

Header Layering and Miniapp Container Isolation​

The template header (live header, or its prerender placeholder) renders inside a .runtime-template-header layer: position: relative; z-index: 1; flex: none. #miniapp-container carries isolation: isolate, so the miniapp's own z-index values stay inside the container and never paint over the header or its inline dropdowns (the growth-rc profile menu is position: absolute; z-index: 13). Miniapp popups portalled to document.body are outside the container and unaffected. This holds in light DOM and when the host renders the runtime inside a shadow root.

Contract for miniapps: an overlay rendered inside the miniapp tree always paints under the host header, even with position: fixed and a high z-index, and the header stays clickable above its backdrop. That covers fullscreen loaders, lightboxes and mobile drawers. Fullscreen overlays must portal to document.body. Design-system modals already do.

The layer also carries an unlayered <style> scoped to it that keeps the header's design-system Buttons on design-system 14 layout (.button__content: display: flex; overflow: visible; white-space: inherit; text-overflow: clip; padding: 0). A federated miniapp bundling design-system 13.0–13.16 otherwise restyles them through its global CSS (same class names, same ds-atoms layer), which clips the header logo.

Observer Wiring​

On bootstrap, 8 observers connect context modules to miniapp setters and update IRuntimePublicState accordingly.