Home

Types

Complete TypeScript type definitions for the RIXL SDK

Component Props

VideoProps

interface VideoProps {
  id?: string;
  src?: string;
  videoData?: VideoData;
  className?: string;

  autoPlay?: boolean;
  muted?: boolean;
  loop?: boolean;
  playsInline?: boolean;
  poster?: string;
  thumbhash?: string;
  volume?: number;

  controls?: boolean;
  theme?: RixlVideoTheme;
  hideUI?: boolean;
  progressBar?: boolean;
  showChapters?: boolean;
  chapters?: Chapter[];
  heatmap?: boolean;
  heatmapData?: VideoHeatmap | null;
  hotSegments?: boolean;
  resumeProgress?: boolean;
  soundDisabled?: boolean;
  autoHideMs?: number;
  allowPlayPause?: boolean;
  allowFullscreen?: boolean;
  allowPictureInPicture?: boolean;

  feedId?: string;
  postId?: string;
  isCurrent?: boolean;
  feedFont?: FontFamilyKey;
  lang?: string;
  userId?: string;
  userProperties?: Record<string, string>;
  planType?: "free" | "pro" | "pay-as-you-go" | "custom";

  analytics?: boolean;
  analyticsPage?: Page;
  onRixlAnalytics?: (event: CustomEvent<{event: AnalyticsEvent}>) => void;
}

type RixlVideoTheme = "default" | "minimal" | "feed" | "hover" | "hideUI";
type Page = "feed" | "standalone" | "profile";

VideoProps is a @lit/react wrapper around <rixl-video>. The React component maps the id prop to videoId and forwards all other props to the Lit element.

VideoPlayerProps

interface VideoPlayerProps {
  children?: ReactNode;
}

VideoPlayer establishes a legacy player scope for detached controls. Render hook consumers as siblings of <Video> inside <VideoPlayer> to share state. The new Lit-backed <Video> does not automatically register itself in the legacy player stores; custom controls built with hooks must be wired to a player scope explicitly.

ImageProps

interface ImageProps {
  id?: string;
  imageData?: ImageData;
  alt?: string;
  className?: string;
  analytics?: boolean;
  analyticsPage?: Page;
  feedId?: string;
  postId?: string;
  isCurrent?: boolean;
  onRixlAnalytics?: (event: CustomEvent<{event: AnalyticsEvent}>) => void;
}

type Page = "feed" | "standalone" | "profile";

The React Image wrapper maps id to imageId and forwards alt, imageData, className, and the analytics props to <rixl-image>.

FeedProps

interface FeedProps {
  feedId: string;
  analytics?: boolean;
  analyticsPage?: Page;
  onRixlAnalytics?: (event: CustomEvent<{event: AnalyticsEvent}>) => void;
  loop?: boolean;
  autoscroll?: boolean;
  muted?: boolean;
  lang?: string;
  feedFont?: FontFamilyKey;
  initialIndex?: number;
  safeAreaTabBar?: number;
  posts?: FeedPost[];
  onFetchMore?: () => void | Promise<void>;
}

type Page = "feed" | "standalone" | "profile";

type FontFamilyKey =
  | "monospace_serif" | "proportional_serif" | "monospace_sans"
  | "proportional_sans" | "casual" | "cursive" | "small_caps";

Feed is a @lit/react wrapper around <rixl-feed>. creatorId and startPostId are accepted for backward compatibility but are not used.

Hook Types

Player-Scoped Hooks

These hooks read state from the enclosing player scope. Call them inside a component rendered as a child of <VideoPlayer>. They take no arguments and bind to the current player scope. Note that the new Lit-backed <Video> is a self-contained custom element and does not automatically participate in the player scope; for now, custom controls should be built as siblings inside <VideoPlayer> or use onRixlAnalytics to react to player events.

interface UseMediaSettingsResult {
  muted: boolean;
  volume: number;
  previousVolume: number;
  mute: () => void;
  unmute: () => void;
  toggleMute: () => void;
  setVolume: (volume: number) => void;
}

declare function useMediaSettings(): UseMediaSettingsResult;

interface UsePlaybackResult {
  paused: boolean;
  loading: boolean;
  ended: boolean;
  hasInteracted: boolean;
  playbackRate: number;
  play: () => Promise<void>;
  pause: () => void;
  togglePlay: () => Promise<void>;
  setPlaybackRate: (playbackRate: number) => void;
  pauseOthers: () => void;
}

declare function usePlayback(): UsePlaybackResult;

interface UsePlayerProgressResult {
  currentTime: number;
  duration: number;
  progress: number;
  buffered: number;
  seekTo: (seconds: number) => void;
  seekBy: (deltaSeconds: number) => void;
}

declare function usePlayerProgress(): UsePlayerProgressResult;

interface UsePlayerUIResult {
  controlsVisible: boolean;
  isFullscreen: boolean;
  isPictureInPicture: boolean;
  showControls: () => void;
  hideControls: () => void;
  toggleFullscreen: () => Promise<void>;
  togglePictureInPicture: () => Promise<void>;
}

declare function usePlayerUI(): UsePlayerUIResult;

interface UsePlayerTracksResult {
  audioTrack: number;
  availableAudioTracks: {
    index: number;
    label: string;
    language: string;
    kind: string;
  }[];
  subtitleTrack: number;
  availableSubtitleTracks: {
    index: number;
    label: string;
    language: string;
    kind: string;
  }[];
  setAudioTrack: (trackIndex: number) => void;
  setSubtitleTrack: (trackIndex: number) => void;
}

declare function usePlayerTracks(): UsePlayerTracksResult;

Global Hook

interface UseGlobalPlayerSettingsResult {
  muted: boolean;
  volume: number;
  playbackRate: number;
  preferredQuality: number | undefined;
  preferredAudioLanguage: string | undefined;
  preferredSubtitleLanguage: string | undefined;
  setMuted: (muted: boolean) => void;
  setVolume: (volume: number) => void;
  setPlaybackRate: (rate: number) => void;
  setPreferredQuality: (quality: number | undefined) => void;
  setPreferredAudioLanguage: (language: string | undefined) => void;
  setPreferredSubtitleLanguage: (language: string | undefined) => void;
  pauseAll: () => void;
}

declare function useGlobalPlayerSettings(): UseGlobalPlayerSettingsResult;

To pause every other player relative to the current scope, use the scoped pauseOthers() returned from usePlayback().

DOM Progress Helper

useProgressBar is a lower-level hook for a raw HTMLVideoElement. For the public Video component, prefer usePlayerProgress() when building custom controls.

interface UseProgressBarProps {
  video: HTMLVideoElement | null;
}

declare function useProgressBar(props: UseProgressBarProps): {
  progress: number;
  isDragging: boolean;
  handleDragStart: (event: MouseEvent | TouchEvent) => void;
};

Data Types

VideoData

Represents video metadata returned from the API.

interface VideoData {
  id: string;
  file: FileData;
  poster: ImageData;
  duration: number;
  width: number;
  height: number;
  codec: string;
  bitrate: number;
  framerate: string;
  hdr: boolean;
  chapters?: Chapter[];
  plan_type?: "free" | "pro" | "pay-as-you-go" | "custom";
}

interface Chapter {
  title: string;
  start_time_sec: number;
  end_time_sec: number;
  duration_label: string;
}

ImageData

Represents image metadata returned from the API.

interface ImageData {
  id: string;
  thumbhash: string;
  width: number;
  height: number;
  attached_to_video: boolean;
  file: FileData;
}

FeedPost

Represents a post within a feed.

interface FeedPost {
  id: string;
  creatorId: string;
  type: "image" | "video";
  feedId: string;
  description: string;
  image?: ImageData;
  video?: VideoData;
  createdAt: string;
}

interface FeedPostsResponse {
  posts: FeedPost[];
  total: number;
  offset: number;
  limit: number;
}

FileData

Represents file metadata for videos and images.

interface FileData {
  id: string;
  project_id: string;
  format: string;
  url: string;
  name: string;
  size: number;
  status: FileStatus;
  created_at: Date;
  updated_at: Date;
}

type FileStatus = "uploading" | "uploaded" | "processing" | "ready" | "error";

Analytics Types

AnalyticsEvent

Union of all events that can be sent through postAnalytics or dispatched via rixl-analytics.

type AnalyticsEvent =
  | ContentViewEvent
  | EngagementEvent
  | InteractionEvent
  | ErrorEvent
  | SessionStartEvent;

type ContentType = "video" | "image";
type ViewType = "start" | "watch" | "end";
type Page = "feed" | "standalone" | "profile";

ContentViewEvent

interface ContentViewEvent {
  _type: "content_views";
  timestamp?: number;
  content_id: string;
  content_type: ContentType;
  view_type: ViewType;
  watch_duration_ms: number;
  page: Page;
  feed_id?: string;
  post_id?: string;
  video_position_ms?: number;
  video_total_duration_ms?: number;
  segments?: Segment[];
  device_id?: string;
  country?: string;
}

interface Segment {
  start_ms: number;
  end_ms: number;
  speed: number;
}

VideoAnalyticsPayload

Returned from buildVideoAnalyticsPayload and used to populate the video-specific fields of a ContentViewEvent.

interface VideoAnalyticsPayload {
  videoPositionMs?: number;
  videoTotalDurationMs?: number;
  segments?: Segment[];
}

interface BuildVideoAnalyticsPayloadParams {
  contentType: ContentType;
  viewType: ViewType;
  video?: {currentTime: number; duration: number} | null;
  playerId?: string;
}

VideoHeatmap

Viewer engagement heatmap data.

interface VideoHeatmap {
  video_id: string;
  total_duration_ms: number;
  data: number[];
}

HotSegment

Represents a high-engagement segment of a video.

interface HotSegment {
  start_second: number;
  end_second: number;
  multiplier: number;
}

EngagementEvent

Sent for user engagement actions such as comments, likes, shares, saves, and subscriptions.

interface EngagementEvent {
  _type: "engagement";
  timestamp?: number;
  engagement_type: string;
  resource_type?: string;
  resource_id?: string;
  page?: string;
  comment_text?: string;
  share_platform?: string;
  country?: string;
  device_type?: string;
  session_id?: string;
}

InteractionEvent

Tracks user actions such as play, pause, seek, image_click, and feed-level interactions.

interface InteractionEvent {
  _type: "interaction";
  timestamp?: number;
  interaction_type: string;
  element_type?: string;
  element_id?: string;
  session_id?: string;
  page?: string;
  page_url?: string;
  scroll_depth?: number;
  search_query?: string;
  click_x?: number;
  click_y?: number;
  device_type?: string;
  browser?: string;
  resource_id?: string;
  resource_type?: string;
  feed_id?: string;
  post_id?: string;
  content_id?: string;
}

ErrorEvent

Tracks media and API load failures.

interface ErrorEvent {
  _type: "error";
  timestamp?: number;
  error_type: string;
  error_code?: string;
  error_message?: string;
  stack_trace?: string;
  resource_type?: string;
  resource_id?: string;
  endpoint?: string;
  session_id?: string;
  device_type?: string;
  browser?: string;
  os?: string;
}

SessionStartEvent

Automatically prepended to the first analytics flush for the session.

interface SessionStartEvent {
  _type: "session_start";
  timestamp?: number;
  utm_source?: string;
  utm_campaign?: string;
  browser?: string;
  language?: string;
  screen_resolution?: string;
  platform?: string;
  tg_platform?: string;
  tg_version?: string;
  timezone?: string;
  timezone_offset?: number;
  color_depth?: number;
  touch_support?: boolean;
  country?: string;
  user_id?: string;
}

AnalyticsContext

Merged into the analytics session_start event and used by builders to fill contextual fields.

interface AnalyticsContext {
  user_id?: string;
  country?: string;
  city?: string;
  region?: string;
  device?: string;
  os?: string;
  os_version?: string;
  language?: string;
  browser?: string;
  screen_resolution?: string;
  platform?: string;
  tg_platform?: string;
  tg_version?: string;
  timezone?: string;
  timezone_offset?: number;
  color_depth?: number;
  touch_support?: boolean;
  utm_source?: string;
  utm_campaign?: string;
}

Helper Parameter Types

interface BuildEventParams {
  contentId: string;
  contentType: ContentType;
  viewType: ViewType;
  watchDurationMs: number;
  page: Page;
  feedId?: string;
  postId?: string;
  videoPositionMs?: number;
  videoTotalDurationMs?: number;
  segments?: Segment[];
}

interface BuildEngagementParams {
  engagementType: string;
  resourceType?: string;
  resourceId?: string;
  page?: string;
  commentText?: string;
  sharePlatform?: string;
  country?: string;
  deviceType?: string;
  sessionId?: string;
}

interface BuildInteractionParams {
  interactionType: string;
  elementType?: string;
  elementId?: string;
  sessionId?: string;
  page?: string;
  pageUrl?: string;
  scrollDepth?: number;
  searchQuery?: string;
  clickX?: number;
  clickY?: number;
  deviceType?: string;
  browser?: string;
  resourceId?: string;
  resourceType?: string;
  feedId?: string;
  postId?: string;
  contentId?: string;
}

interface BuildErrorParams {
  errorType: string;
  errorCode?: string;
  errorMessage?: string;
  stackTrace?: string;
  resourceType?: string;
  resourceId?: string;
  endpoint?: string;
  sessionId?: string;
  deviceType?: string;
  browser?: string;
  os?: string;
}

interface BuildSessionStartParams {
  browser?: string;
  language?: string;
  screenResolution?: string;
  platform?: string;
  tgPlatform?: string;
  tgVersion?: string;
  timezone?: string;
  timezoneOffset?: number;
  colorDepth?: number;
  touchSupport?: boolean;
  country?: string;
  userId?: string;
  utmSource?: string;
  utmCampaign?: string;
}

Wire format notes

  • postAnalytics queues events and flushes them in a micro-task.
  • The first flush automatically prepends one session_start event.
  • All millisecond durations are converted to GoogleProtobufDuration strings ("5s", "1.234s") before sending to /analytics/v1/events.
  • content_type is sent as MEDIA_TYPE_IMAGE or MEDIA_TYPE_VIDEO on the wire.