SDKsWeb SDK

Examples

Web SDK integration examples for React, Vue 3, Angular, and vanilla JS

Copy-paste examples showing how to integrate the SDK in the most common frameworks. Each one mounts the widget on load and calls destroy() on unmount, so the connection and media tracks are always cleaned up.

In every example, token comes from your backend after creating a session — see Create a session.

import React, { useEffect, useRef } from "react";
import { NapsterCompanionApiSdk } from "@touchcastllc/napster-companion-api";
import type { NapsterCompanionApiInstance } from "@touchcastllc/napster-companion-api";
import "@touchcastllc/napster-companion-api/styles";

export function CompanionWidget({ token }: { token: string }) {
  const containerRef = useRef<HTMLDivElement>(null);
  const instanceRef = useRef<NapsterCompanionApiInstance | null>(null);

  useEffect(() => {
    const initSDK = async () => {
      if (!containerRef.current) return;

      const result = await NapsterCompanionApiSdk.init(token, {
        mountContainer: containerRef.current,
        position: "bottom-right",
      });
      instanceRef.current = result;
    };

    initSDK();

    return () => {
      instanceRef.current?.destroy();
    };
  }, []);

  return <div ref={containerRef} style={{ width: "100%", height: "100%" }} />;
}
<template>
  <div ref="containerRef"></div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";
import { NapsterCompanionApiSdk } from "@touchcastllc/napster-companion-api";
import type { NapsterCompanionApiInstance } from "@touchcastllc/napster-companion-api";
import "@touchcastllc/napster-companion-api/styles";

const props = defineProps<{ token: string }>();
const containerRef = ref<HTMLElement>();
let instance: NapsterCompanionApiInstance | null = null;

onMounted(async () => {
  if (!containerRef.value) return;

  instance = await NapsterCompanionApiSdk.init(props.token, {
    mountContainer: containerRef.value,
    position: "bottom-right",
  });
});

onUnmounted(() => {
  instance?.destroy();
});
</script>
import {
  Component,
  OnInit,
  OnDestroy,
  ElementRef,
  ViewChild,
  Input,
} from "@angular/core";
import {
  NapsterCompanionApiSdk,
  NapsterCompanionApiInstance,
} from "@touchcastllc/napster-companion-api";

@Component({
  selector: "app-companion",
  template: "<div #containerRef></div>",
})
export class CompanionComponent implements OnInit, OnDestroy {
  @Input() token!: string;
  @ViewChild("containerRef") containerRef!: ElementRef<HTMLDivElement>;
  private instance: NapsterCompanionApiInstance | null = null;

  async ngOnInit() {
    this.instance = await NapsterCompanionApiSdk.init(this.token, {
      mountContainer: this.containerRef.nativeElement,
      position: "bottom-right",
    });
  }

  ngOnDestroy() {
    this.instance?.destroy();
  }
}
<div id="sdk-container"></div>
<script src="https://cdn.jsdelivr.net/npm/@touchcastllc/napster-companion-api@latest/lib/index.standalone.js"></script>
<script>
  // token comes from your server after calling POST /public/agents/{agentId}/connections
  const sdk = window.napsterCompanionApiSDK;

  sdk.init(token, {
    mountContainer: "#sdk-container",
    position: "bottom-right",
  });
</script>

Initialize the SDK after the mount container exists in the DOM. In React, Vue, and Angular the lifecycle hooks above guarantee this. In plain HTML, put the init call after the container element, or wrap it in a DOMContentLoaded listener.

Next steps

On this page