Own UI betslip

Native betslip with EXTERNAL mode and onEvent.

Guide: Own UI

When your app already has a betslip, set mode: 'EXTERNAL', listen for outcome_selected on onEvent, and notify the Web SDK after your sportsbook responds (embet.notifyBetPlaced — see Betslip (feature)). Do not pass onPlaceBet.

This recipe covers the React Native shell and selection handling. Wire notifyBetPlaced through your WebView bridge (for example a custom htmlUrl page) as described on Own UI.

npm install @livelike/embet-rn react-native-webview
import { useRef, useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import {
  EmbetOverlay,
  type EmbetOverlayRef,
} from '@livelike/embet-rn';

const CLIENT_ID = 'YOUR_CLIENT_ID';
const EVENT_ID = 'YOUR_EVENT_ID';

type Selection = { marketId: string; outcomeId: string };

export function EmbetExternalBetslipScreen() {
  const overlayRef = useRef<EmbetOverlayRef>(null);
  const [selection, setSelection] = useState<Selection | null>(null);

  const onInitialized = () => {
    overlayRef.current?.configureBetSlip({
      mode: 'EXTERNAL',
      currency: '€',
      currencyDisplay: 'prefix',
      decimalSign: ',',
      maxAmount: 1000,
    });
    overlayRef.current?.configureResize({
      enabled: true,
      hostElement: 'body',
    });
  };

  const onEvent = (event: { eventName: string; payload: Record<string, unknown> }) => {
    if (event.eventName === 'outcome_selected') {
      setSelection({
        marketId: String(event.payload.marketId),
        outcomeId: String(event.payload.outcomeId),
      });
    }
  };

  async function onHostPlaceBet(stake: number) {
    if (!selection) return;

    const result = await placeBetWithYourSportsbook({ ...selection, stake });

    // Notify embet.notifyBetPlaced inside the WebView (custom bridge / htmlUrl).
    await notifyEmbetBetPlaced({
      marketId: selection.marketId,
      outcomeId: selection.outcomeId,
      stake,
      accepted: result.accepted,
      errorCode: result.errorCode,
    });

    if (result.accepted) setSelection(null);
  }

  return (
    <View style={styles.row}>
      <View style={styles.overlay}>
        <EmbetOverlay
          ref={overlayRef}
          clientId={CLIENT_ID}
          customId={EVENT_ID}
          sdkVersion="1.4.0"
          onInitialized={onInitialized}
          onEvent={onEvent}
        />
      </View>
      <View style={styles.betslip}>
        <Text style={styles.title}>Your betslip</Text>
        {selection ? (
          <Text>{selection.marketId} / {selection.outcomeId}</Text>
        ) : (
          <Text>Select an outcome in the overlay.</Text>
        )}
        <Button
          title="Place bet"
          disabled={!selection}
          onPress={() => onHostPlaceBet(10)}
        />
      </View>
    </View>
  );
}

async function placeBetWithYourSportsbook(_selection: unknown) {
  return { accepted: true as const, errorCode: undefined };
}

/** Bridge to your WebView — implement with htmlUrl + embet.notifyBetPlaced */
async function notifyEmbetBetPlaced(_args: {
  marketId: string;
  outcomeId: string;
  stake: number;
  accepted: boolean;
  errorCode?: string;
}) {
  // See doc:react-native-betslip-own-ui
}

const styles = StyleSheet.create({
  row: { flex: 1, flexDirection: 'row' },
  overlay: { flex: 1 },
  betslip: { width: 280, padding: 16, borderLeftWidth: 1, borderColor: '#ccc' },
  title: { fontSize: 18, fontWeight: '600', marginBottom: 8 },
});