Skip to main content
DocsSDKUI SDK (@creatiq/ui-sdk)
Back to docs

UI SDK (@creatiq/ui-sdk)

Browser, player, editor, collections, AI, picker, workspace exports

sdk
ui-sdk

@creatiq/ui-sdk Reference

Overview

@creatiq/ui-sdk is a React component library that packages Creatiq's content management, AI generation, and H5P player/editor functionality as embeddable components. The SDK allows external applications (LMS platforms, corporate portals, whitelabel products) to integrate Creatiq's features without hosting the Creatiq backend -- the backend remains at creatiq.app while the SDK provides the UI layer.

The SDK ships 9 export paths, each independently tree-shakeable:

Export PathPurpose
@creatiq/ui-sdkRoot -- provider, hooks, types, player, editor, picker, workspace
@creatiq/ui-sdk/browserContent browsing components (grid, filters, cards)
@creatiq/ui-sdk/playerH5P content player (iframe-based)
@creatiq/ui-sdk/editorH5P content editor (iframe-based)
@creatiq/ui-sdk/collectionsCollection management UI
@creatiq/ui-sdk/aiAI copilot for content generation
@creatiq/ui-sdk/uiShared UI primitives (Radix-based)
@creatiq/ui-sdk/pickerContent picker sheet (3-tab selector)
@creatiq/ui-sdk/workspaceFull workspace embed (all views)

Installation

npm install @creatiq/ui-sdk

Peer Dependencies

{
  "react": "^18.0.0",
  "react-dom": "^18.0.0",
  "@lumieducation/h5p-react": "^10.0.0",
  "@lumieducation/h5p-server": "^10.0.0"
}

CSS Import

The SDK ships a bundled CSS file that must be imported once:

import '@creatiq/ui-sdk/styles.css';

Configuration -- CreatiqProvider

All SDK components must be wrapped in <CreatiqProvider>. This component:

  • Injects configuration, authentication, and theme into the React tree
  • Fetches user profile and plan features on mount via GET /api/auth/me
  • Applies theme CSS custom properties to :root
  • Handles token refresh via the onTokenExpired callback

Setup

import { CreatiqProvider } from '@creatiq/ui-sdk';
import '@creatiq/ui-sdk/styles.css';

function App() {
  return (
    <CreatiqProvider
      config={{
        baseUrl: 'https://creatiq.app',
        token: '<sdk-token>',
        locale: 'en',
        theme: {
          colorPrimary: '#6366f1',
          borderRadius: '0.5rem',
        },
        ai: {
          enabled: true,
          features: { chat: true, bulkGenerate: true, remix: true },
        },
        onTokenExpired: async () => {
          // Call your backend to get a fresh SDK token
          const res = await fetch('/api/creatiq/refresh-token');
          const { token } = await res.json();
          return token;
        },
      }}
    >
      {/* SDK components go here */}
    </CreatiqProvider>
  );
}

CreatiqConfig

interface CreatiqConfig {
  baseUrl: string;                              // Creatiq API base URL
  token: string;                                // SDK token (from POST /api/sdk/token)
  locale?: 'en' | 'tr' | 'fr' | 'es' | 'ar';  // UI locale (default: 'en')
  theme?: Partial<CreatiqTheme>;                // Theme overrides
  ai?: CreatiqAIConfig;                         // AI module config (undefined = disabled)
  onTokenExpired?: () => Promise<string>;       // Token refresh callback
  onLogout?: () => void;                        // Logout callback
  onLocaleChange?: (locale: string) => void;    // Locale change callback
  tenantId?: string;                            // Optional tenant identifier
}

CreatiqTheme

Theme tokens are injected as CSS custom properties prefixed with --crq-:

PropertyCSS Variable
colorPrimary--crq-color-primary
colorPrimaryForeground--crq-color-primary-foreground
colorBackground--crq-color-background
colorSurface--crq-color-surface
colorText--crq-color-text
colorMuted--crq-color-muted
colorBorder--crq-color-border
colorDestructive--crq-color-destructive
borderRadius--crq-border-radius
fontFamily--crq-font-family

CreatiqAIConfig

interface CreatiqAIConfig {
  enabled: boolean;
  features?: {
    chat?: boolean;
    bulkGenerate?: boolean;
    remix?: boolean;
    imageAnalysis?: boolean;
    videoAnalysis?: boolean;
  };
}

Context Hooks

useCreatiq()         // Full context (config, user, features, getToken, refreshToken, apiUrl)
useCreatiqConfig()   // SDK configuration only
useCreatiqUser()     // Authenticated user (CreatiqUser | null)
useCreatiqFeatures() // Plan features and usage limits (CreatiqFeatures | null)

CreatiqUser

interface CreatiqUser {
  id: string;
  email: string;
  name: string;
  role: string;
  plan: 'free' | 'pro' | 'premium';
}

CreatiqFeatures

interface CreatiqFeatures {
  plan: string;
  contentTypes: string[];
  limits: {
    monthlyGenerations: number;
    remainingGenerations: number;
    monthlyContents: number;
    remainingContents: number;
  };
  flags: Record<string, boolean>;
}

Export Modules

@creatiq/ui-sdk/browser

Content browsing and filtering components. Renders the user's H5P content library with search, filters, and sorting.

Components:

ComponentDescription
ContentBrowserFull content browser with filters, search, grid/list toggle
ContentCardIndividual content card with actions (play, edit, export, delete)
ContentCardListContent list layout
ContentFiltersFilter controls (content type, framework, grade, subject, difficulty)
ContentEmptyStateEmpty state placeholder
ContentSkeletonLoading skeleton
DifficultyBadgeDifficulty level badge
PublicContentBrowserCommunity marketplace browser with pagination
PublicContentCardPublic content card
CurriculumFiltersCurriculum-specific filter controls

Utilities:

ExportDescription
CONTENT_TYPE_CONFIGMap of H5P content type metadata (icon, label, category)
getContentTypeConfig(slug)Get config for a content type slug
getContentTypeLabelBySlug(slug)Get display label for a content type

Usage:

import { ContentBrowser } from '@creatiq/ui-sdk/browser';
import { useContentBrowser } from '@creatiq/ui-sdk';

function MyContentPage() {
  const browser = useContentBrowser();

  useEffect(() => {
    browser.loadContents();
  }, []);

  return (
    <ContentBrowser
      contents={browser.contents}
      filteredContents={browser.filteredContents}
      loading={browser.loading}
      displayMode="grid"
      // ... filter props from browser hook
    />
  );
}

@creatiq/ui-sdk/player

Iframe-based H5P content player. Renders content via {baseUrl}/embed/{contentId} and communicates through postMessage.

Exports:

ExportDescription
CreatiqPlayerPlayer component
isCreatiqMessage(data)Type guard for child-to-parent messages
isCreatiqParentMessage(data)Type guard for parent-to-child messages
ParentMessageUnion type for SDK-to-iframe messages
ChildMessageUnion type for iframe-to-SDK messages

CreatiqPlayerProps:

interface CreatiqPlayerProps {
  contentId: string;                              // H5P content ID
  onXAPIStatement?: (statement: unknown) => void; // xAPI statement callback
  onReady?: (contentId: string) => void;          // Content loaded callback
  onError?: (error: string) => void;              // Error callback
  onFullscreen?: (active: boolean) => void;       // Fullscreen toggle callback
  className?: string;                             // Wrapper div class
  minHeight?: number;                             // Min height in px (default: 200)
  maxHeight?: number;                             // Max height in px (default: none)
  fillContainer?: boolean;                        // Fill parent height (default: false)
}

Usage:

import { CreatiqPlayer } from '@creatiq/ui-sdk/player';

<CreatiqPlayer
  contentId="abc123"
  onXAPIStatement={(stmt) => console.log('xAPI:', stmt)}
  onReady={(id) => console.log('Ready:', id)}
  minHeight={300}
/>

The player automatically:

  • Builds the iframe URL with token authentication
  • Listens for creatiq:resize messages and adjusts height
  • Forwards locale and theme changes to the iframe via postMessage
  • Shows a loading spinner until creatiq:ready is received
  • Validates message origins against config.baseUrl

@creatiq/ui-sdk/editor

Iframe-based H5P content editor. Renders via {baseUrl}/embed/editor/{contentId} for editing, or {baseUrl}/embed/editor/new for creation.

Exports:

ExportDescription
CreatiqEditorEditor component
CreatiqEditorSaveResultSave result type

CreatiqEditorProps:

interface CreatiqEditorProps {
  contentId?: string;                                      // Existing content ID (undefined = new)
  language?: string;                                       // Editor UI language (default: config.locale)
  onSave?: (result: CreatiqEditorSaveResult) => void;      // Content saved callback
  onContentChanged?: () => void;                           // Dirty flag callback
  onError?: (error: string) => void;                       // Error callback
  onReady?: (contentId: string) => void;                   // Editor loaded callback
  className?: string;                                      // Wrapper div class
  height?: number;                                         // Height in px (default: 600)
}

interface CreatiqEditorSaveResult {
  contentId: string;
  metadata: unknown;
}

Usage:

import { CreatiqEditor } from '@creatiq/ui-sdk/editor';

// Edit existing content
<CreatiqEditor
  contentId="abc123"
  onSave={(result) => console.log('Saved:', result.contentId)}
  height={700}
/>

// Create new content
<CreatiqEditor
  onSave={(result) => console.log('Created:', result.contentId)}
/>

@creatiq/ui-sdk/collections

Collection management components for organizing H5P content into curated sets.

Components:

ComponentDescription
CollectionListGrid of collection cards
CollectionCardSingle collection card with metadata
CollectionDetailFull collection view with items, reordering, suggestions
CollectionItemCardIndividual item within a collection
CollectionCreateModalModal for creating new collections with curriculum metadata
CollectionPickerModalModal for selecting an existing collection
ContentPickerModalModal for adding content to a collection
ContentPreviewModalContent preview overlay
BloomsDistributionChartBloom's taxonomy distribution chart
LibraryPickerContent picker from user's library
CommunityPickerContent picker from community marketplace

Data hooks (from root export):

useCollections()                  // List, create, delete collections
useCollectionDetail(collectionId) // Detail view, items, suggestions, CRUD

Usage:

import { CollectionList, CollectionCard } from '@creatiq/ui-sdk/collections';
import { useCollections } from '@creatiq/ui-sdk';

function MyCollections() {
  const { collections, isLoading, createCollection, deleteCollection } = useCollections();

  return (
    <div className="grid grid-cols-2 gap-4">
      {collections.map((c) => (
        <CollectionCard
          key={c.id}
          collection={c}
          onClick={(id) => navigate(`/collections/${id}`)}
          onDelete={deleteCollection}
        />
      ))}
    </div>
  );
}

@creatiq/ui-sdk/ai

AI copilot module for AI-powered H5P content generation. This is the largest SDK module, providing a full multi-screen generation wizard.

Main Components:

ComponentDescription
CreatiqAISidebarFull sidebar with view routing (Home -> Generate -> Result -> Chat)

CreatiqAISidebarProps:

interface CreatiqAISidebarProps {
  onContentCreated?: (content: { contentId: string; params: unknown; library: string }) => void;
  onClose?: () => void;
  collapsed?: boolean;
  onToggleCollapse?: () => void;
  onCreateContent?: (content: { library: string; params: unknown; tempImageFiles?: string[] }, title?: string) => Promise<void>;
  courseContext?: CourseCreationContext | null;
  language?: string;
  userPlan?: string;
  className?: string;
}

Views (CreatiqAIView): 'home' | 'generate' | 'result' | 'chat'

Source Types (SourceType): 'topic' | 'document' | 'video' | 'url' | 'image' | 'remix'

Generation Modes: 'single' | 'bulk' | 'differentiated' | 'remix' | 'scenario'

Sub-components (30+ exported):

  • Views: AIHome, AIHeader, ResultView, ChatView, Onboarding, Upsell, CurriculumBar
  • Generate screens: GenerateText, GenerateDocument, GenerateVideo, GenerateUrl, GenerateImage, GenerateRemix, GenerateScreenShell
  • Result views: ResultBulkView, ResultDiffView, ResultQualitySection, ResultActionButtons, ContentPreview
  • Utilities: BloomsBadge, BloomsDistributionChart, QualityBadge, RemixMenu, BaseDropZone, FileDropZone, ImageDropZone, SelectField, DecisionTreePreview, StockImagePicker, ContentTypeCard, ContentTypeGrid, TopicSelector, TypingIndicator

Hooks:

HookDescription
useCreatiqAI()Main generation hook (generate function, API client, store access)
useAIChat()Chat conversation management
useTextGeneration()Text-based content generation
useDocumentGeneration()Document upload and generation
useVideoGeneration()Video analysis and generation
useImageGeneration()Image analysis and generation
useBulkGeneration()Bulk content generation
useMultimodalGeneration()Multimodal (video/image) generation
useContentTypeRegistry()H5P content type registry
useStockImageSearch()Stock image search

Store:

useCreatiqAIStore() // Zustand store for AI panel state, generation state, chat messages, preferences

The store persists user preferences (language, difficulty) to localStorage under key creatiq-ai-store.

API Client:

createAIApi(ctx) // Returns CreatiqAIApiClient with methods for all AI endpoints

Usage:

import { CreatiqAISidebar } from '@creatiq/ui-sdk/ai';

<CreatiqAISidebar
  onContentCreated={(content) => {
    console.log('Created:', content.contentId);
  }}
  courseContext={{
    frameworkCode: 'CCSS',
    gradeCode: '5',
    subjectCode: 'MATH',
  }}
  language="en"
  userPlan="pro"
/>

@creatiq/ui-sdk/ui

Shared UI primitives built on Radix UI. These are the building blocks used by all other SDK modules.

Components:

ComponentBased On
Button, buttonVariantsCustom with CVA
InputCustom
Label@radix-ui/react-label
Badge, badgeVariantsCustom with CVA
Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContentCustom
Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription@radix-ui/react-dialog
Tooltip, TooltipTrigger, TooltipContent, TooltipProvider@radix-ui/react-tooltip
SkeletonCustom
ScrollArea, ScrollBar@radix-ui/react-scroll-area
Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton@radix-ui/react-select
Popover, PopoverTrigger, PopoverContent@radix-ui/react-popover
TextareaCustom
Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription@radix-ui/react-dialog
Tabs, TabsList, TabsTrigger, TabsContent@radix-ui/react-tabs
Toast, ToastProvider, ToastViewport, ToastTitle, ToastDescription, ToastClose, ToastAction@radix-ui/react-toast

@creatiq/ui-sdk/picker

Content picker sheet -- a slide-out panel with three tabs for selecting H5P content from multiple sources.

Exports:

ExportDescription
ContentPickerSheetSheet component with My Content, Collections, Community tabs
ContentPickerSheetPropsProps type
SelectedContentItemSelected item type

ContentPickerSheetProps:

interface ContentPickerSheetProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  existingContentIds?: string[];                           // IDs to disable (already attached)
  onContentSelected: (items: SelectedContentItem[]) => void; // Selection callback
  title?: string;                                          // Custom sheet title
}

interface SelectedContentItem {
  contentId: string;
  title: string;
  contentType: string;
  contentTypeSlug: string;
  thumbnailUrl?: string | null;
}

Tabs:

  1. My Content -- User's own H5P content library with filters
  2. Collections -- Browse collections, drill into collection items
  3. Community -- Public marketplace content

Usage:

import { ContentPickerSheet } from '@creatiq/ui-sdk/picker';

const [open, setOpen] = useState(false);

<ContentPickerSheet
  open={open}
  onOpenChange={setOpen}
  existingContentIds={['id1', 'id2']}
  onContentSelected={(items) => {
    items.forEach((item) => attachContent(item.contentId));
  }}
/>

@creatiq/ui-sdk/workspace

Full workspace embed that bundles all views into a single component with top-bar navigation and animated view switching.

Exports:

ExportDescription
CreatiqWorkspaceFull workspace component
WorkspaceTopBarContext-aware navigation bar (also usable standalone)

WorkspaceView: 'collections' | 'collection-detail' | 'smart-collection' | 'create' | 'play' | 'settings'

CreatiqWorkspaceProps:

interface CreatiqWorkspaceProps {
  defaultView?: WorkspaceView;                                // Initial view (default: 'collections')
  onContentCreated?: (content: { contentId: string }) => void; // Content created callback
  onViewChange?: (view: WorkspaceView) => void;                // View change callback
  className?: string;
  compact?: boolean;                                           // Compact mode for embed
  searchQuery?: string;                                        // External search query
}

Views:

  • collections -- Grid of collections with search and create actions
  • collection-detail -- Single collection with items, reordering
  • smart-collection -- Virtual collections (uncategorized, recent)
  • create -- H5P editor with AI wizard
  • play -- H5P player
  • settings -- User settings

Usage:

import { CreatiqWorkspace } from '@creatiq/ui-sdk/workspace';

<div style={{ height: '100vh' }}>
  <CreatiqWorkspace
    defaultView="collections"
    onContentCreated={(c) => console.log('Created:', c.contentId)}
    onViewChange={(view) => console.log('View:', view)}
  />
</div>

Data Hooks (Root Export)

These hooks are exported from the root @creatiq/ui-sdk path and use useSdkFetch internally for authenticated API calls.

useContentBrowser

Provides content browsing, filtering, sorting, visibility toggle, delete, and export.

const {
  contents,              // ContentItem[]
  filteredContents,      // Filtered and sorted array
  loading,               // boolean
  searchQuery,           // string
  contentTypeFilter,     // string | null
  frameworkFilter,       // string | null
  gradeFilter,           // string | null
  subjectFilter,         // string | null
  difficultyFilter,      // string | null
  sortBy,                // 'newest' | 'oldest' | 'az' | 'za' | 'quality'
  availableContentTypes, // string[] (derived from contents)
  availableFrameworks,   // string[]
  availableGrades,       // string[]
  availableSubjects,     // string[]
  setSearchQuery,
  setContentTypeFilter,
  setFrameworkFilter,
  setGradeFilter,
  setSubjectFilter,
  setDifficultyFilter,
  setSortBy,
  loadContents,          // () => Promise<void>
  handleToggleVisibility,
  deleteContent,
  exportContent,
} = useContentBrowser();

useCollections

const {
  collections,       // Collection[]
  total,             // number
  isLoading,         // boolean
  error,             // string | null
  loadCollections,   // (offset?, limit?) => Promise<void>
  createCollection,  // (data: CreateCollectionPayload) => Promise<Collection>
  deleteCollection,  // (id: string) => Promise<void>
} = useCollections();

useCollectionDetail

const {
  detail,               // CollectionDetail | null
  suggestions,          // CollectionSuggestions | null
  isLoading,
  isSuggestionsLoading,
  error,
  loadDetail,           // (id: string) => Promise<void>
  loadSuggestions,      // (id: string) => Promise<void>
  updateCollection,     // (updates: UpdateCollectionPayload) => Promise<void>
  addItem,              // (contentId: string) => Promise<void>
  addItems,             // (contentIds: string[]) => Promise<void>
  removeItem,           // (itemId: string) => Promise<void>
  reorderItems,         // (items: { id, position }[]) => Promise<void>
} = useCollectionDetail(collectionId);

usePublicContents

const {
  contents,      // PublicContentItem[]
  total,         // number
  filter,        // PublicContentFilter
  isLoading,
  error,
  facets,        // MarketplaceFacets | null
  updateFilter,  // (updates: Partial<PublicContentFilter>) => void
  nextPage,
  prevPage,
  refetch,
} = usePublicContents(initialFilter?);

API Utilities

sdkFetch

Low-level fetch utility with automatic token injection, 401 retry with token refresh, and 30-second timeout.

import { sdkFetch } from '@creatiq/ui-sdk';

const result = await sdkFetch<MyType>(ctx, '/api/some-endpoint', {
  method: 'POST',
  body: JSON.stringify(data),
});

useSdkFetch

Hook providing typed HTTP helpers bound to the current SDK context.

const { get, post, patch, put, del } = useSdkFetch();

const result = await get<ContentItem[]>('/h5p/content');
const created = await post<Collection>('/api/collections', { title: 'My Set' });

All methods return ApiResponse<T>:

interface ApiResponse<T = unknown> {
  success: boolean;
  data?: T;
  error?: string;
  total?: number;
}

Internationalization

The SDK uses an isolated i18next instance (via i18next.createInstance()) so it never conflicts with the host app's i18n setup.

Supported locales: en, tr, fr, es, ar

Translations are bundled at build time. The SDK locale follows config.locale passed to CreatiqProvider.

import { initSDKI18n, getSDKI18n, resetSDKI18n } from '@creatiq/ui-sdk';

// Initialize with overrides
await initSDKI18n('tr', { 'picker.title': 'Custom Title' });

// Inside components
import { useSDKI18n } from '@creatiq/ui-sdk';
const { t } = useSDKI18n();

Animations

The SDK includes framer-motion animation presets with reduced-motion support.

import {
  fadeInUp, fadeIn, scaleIn, scaleUp,
  pageVariants, panelVariants,
  slideInFromRight, slideInFromLeft,
  staggerContainer, staggerItem,
  counterUp, createStaggerContainer,
  getReducedMotionVariants,
  useReducedMotion, useMotionSafe,
} from '@creatiq/ui-sdk';

useReducedMotion() reads prefers-reduced-motion from the OS and disables animations when enabled.


Build Configuration

The SDK is built with Vite library mode producing both ESM and CJS outputs.

SettingValue
Build toolVite 6 + @vitejs/plugin-react
Type generationvite-plugin-dts
Output formatsESM (.js) + CJS (.cjs)
Output directorydist/
CSSBundled as dist/styles.css
External dependenciesreact, react-dom, react/jsx-runtime, @lumieducation/h5p-react, @lumieducation/h5p-server
Shared chunkshared-context (ensures single CreatiqContext instance across sub-path imports)
Path alias@sdk -> src/

Entry Points

Each export path has its own entry:

src/index.ts              -> dist/index.js + dist/index.cjs
src/browser/index.ts      -> dist/browser/index.js + dist/browser/index.cjs
src/player/index.ts       -> dist/player/index.js + dist/player/index.cjs
src/editor/index.ts       -> dist/editor/index.js + dist/editor/index.cjs
src/collections/index.ts  -> dist/collections/index.js + dist/collections/index.cjs
src/ai/index.ts           -> dist/ai/index.js + dist/ai/index.cjs
src/ui/index.ts           -> dist/ui/index.js + dist/ui/index.cjs
src/picker/index.ts       -> dist/picker/index.js + dist/picker/index.cjs
src/workspace/index.ts    -> dist/workspace/index.js + dist/workspace/index.cjs

Development

npm run dev        # Watch mode
npm run build      # Production build
npm run lint       # ESLint
npm run typecheck  # TypeScript check

Key Types

ContentItem

interface ContentItem {
  id: string;
  title: string;
  mainLibrary: string;
  contentTypeSlug: string;
  createdAt: string;
  updatedAt: string;
  embedTypes?: string[];
  curriculum?: {
    frameworkName: string;
    stageName: string | null;
    gradeName: string;
    subjectName: string;
    topicNames: string[];
    difficulty: string;
    language: string;
  } | null;
  quality?: { overallScore: number; bloomsLevel: string } | null;
  visibility?: 'private' | 'public';
  viewCount?: number;
}

Collection

interface Collection {
  id: string;
  userId: string;
  title: string;
  description: string | null;
  coverImageUrl: string | null;
  visibility: 'private' | 'public';
  frameworkCode: string | null;
  frameworkName: string | null;
  gradeCode: string | null;
  gradeName: string | null;
  subjectCode: string | null;
  subjectName: string | null;
  topicCodes: string[];
  topicNames: string[];
  difficulty: string | null;
  language: string | null;
  itemCount: number;
  createdAt: string;
  updatedAt: string;
}

PostMessage Protocol

// SDK -> iframe (parent -> child)
type ParentMessage =
  | { type: 'creatiq:auth'; token: string }
  | { type: 'creatiq:locale'; locale: string }
  | { type: 'creatiq:theme'; theme: Record<string, string> };

// iframe -> SDK (child -> parent)
type ChildMessage =
  | { type: 'creatiq:ready'; contentId: string }
  | { type: 'creatiq:xapi'; contentId: string; statement: unknown }
  | { type: 'creatiq:resize'; contentId: string; height: number }
  | { type: 'creatiq:error'; contentId: string; message: string }
  | { type: 'creatiq:fullscreen'; contentId: string; active: boolean }
  | { type: 'creatiq:saved'; contentId: string; metadata: unknown }
  | { type: 'creatiq:content-changed'; contentId: string };
Back to docsdocs/product/sdk/ui-sdk.md