π For quick integration, please refer to the Demo Repository! The demo repository provides complete example code including full implementations for Vanilla, Vue, and React to help you get started quickly.
Step 1: Integration
npm install @spatialwalk/avatarkit
yarn add @spatialwalk/avatarkit
pnpm add @spatialwalk/avatarkit
Step 2: Vite Configuration (Recommended)
If youβre using Vite as your build tool, we strongly recommend using our Vite plugin to automatically handle WASM file configuration. The plugin automatically handles all necessary configurations, so you donβt need to set them up manually.
Using the Plugin
Add the plugin to your vite.config.ts:
import { defineConfig } from 'vite'
import { avatarkitVitePlugin } from '@spatialwalk/avatarkit/vite'
export default defineConfig({
plugins: [
avatarkitVitePlugin(), // Add this line
],
})
Plugin Features
The plugin automatically handles:
- β
Development Server: Automatically sets the correct MIME type (
application/wasm) for WASM files
- β
Build Time: Automatically copies WASM files to
dist/assets/ directory
- Smart Detection: Extracts referenced WASM file names (including hash) from JS glue files
- Auto Matching: Ensures copied WASM files match references in JS glue files
- Hash Support: Properly handles WASM files with hash (e.g.,
avatar_core_wasm-{hash}.wasm)
- β
WASM JS Glue: Automatically copies WASM JS glue files to
dist/assets/ directory
- β
Cloudflare Pages: Automatically generates
_headers file to ensure WASM files use the correct MIME type
- β
Vite Configuration: Automatically configures
optimizeDeps, assetsInclude, assetsInlineLimit, and other options
Manual Configuration (Without Plugin)
If youβre not using the Vite plugin, you need to manually configure the following:
import { defineConfig } from 'vite'
export default defineConfig({
optimizeDeps: {
exclude: ['@spatialwalk/avatarkit'],
},
assetsInclude: ['**/*.wasm'],
build: {
assetsInlineLimit: 0,
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name?.endsWith('.wasm')) {
return 'assets/[name][extname]'
}
return 'assets/[name]-[hash][extname]'
},
},
},
},
// Development server needs manual middleware configuration for WASM MIME type
configureServer(server) {
server.middlewares.use((req, res, next) => {
if (req.url?.endsWith('.wasm')) {
res.setHeader('Content-Type', 'application/wasm')
}
next()
})
},
})
Step 3: Get Credentials
Before initializing the SDK, you need to obtain authentication credentials:
App ID:
- Visit the Developer Platform to create your App
- Get your App ID from the platform dashboard
- The App ID is required for SDK initialization
Session Token (Optional but Recommended for SDK Mode):
- For SDK Mode (real-time WebSocket communication), a Session Token is typically required for authentication
- Session Token should be obtained from your backend server
- Your backend server should request the Session Token from the AvatarKit Server
- Session Token has a maximum validity of 1 hour
- Set the Session Token using
AvatarSDK.setSessionToken(token) after SDK initialization
Authentication Flow:
Developer Client β Developer Server β AvatarKit Server β return Session Token (max 1 hour validity)
Important Notes:
- App ID and Session Token are paired and must be used together
- Each App ID corresponds to a specific list of avatars that can be driven
- For testing with publicly available test avatars, you may use default credentials provided in demo repositories
- For production use with your own avatars, you must create your App at the Developer Platform
- Host Mode does not require Session Token as it doesnβt use WebSocket communication
Step 4: Initialize SDK
Initialize the SDK in your application:
import { AvatarSDK, Environment } from '@spatialwalk/avatarkit'
const configuration = {
environment: Environment.cn,
audioFormat: { // Optional, default is { channelCount: 1, sampleRate: 16000 }
channelCount: 1, // Fixed to 1 (mono)
sampleRate: 16000 // Supported: 8000, 16000, 22050, 24000, 32000, 44100, 48000 Hz
}
}
await AvatarSDK.initialize('your-app-id', configuration)
// Set session token (required for SDK mode WebSocket authentication)
// Get the token from your backend server, which should request it from AvatarKit Server
AvatarSDK.setSessionToken('your-session-token')
Step 5: Create Avatar View
Add the avatar renderer in your application:
import { AvatarManager, AvatarView } from '@spatialwalk/avatarkit'
class App {
private avatarView: AvatarView | null = null
async setupAvatar() {
// Load the avatar
const avatarManager = AvatarManager.shared
const avatar = await avatarManager.load('avatar-id', (progress) => {
// Handle download state
console.log(`Loading: ${progress.progress}%`)
})
// Create avatar view
const container = document.getElementById('avatar-container')
if (container) {
this.avatarView = new AvatarView(avatar, container)
await this.avatarView.ready
}
}
}
Step 6: Using Features
β οΈ CRITICAL: Before using any audio-related features, you MUST initialize the audio context in a user gesture context (e.g., click, touchstart event handlers). This is required by browser security policies.
// β οΈ CRITICAL: Initialize audio context first (MUST be called in user gesture context)
button.addEventListener('click', async () => {
// Initialize audio context - MUST be in user gesture context
await avatarView.controller.initializeAudioContext()
// Connect to service
await avatarView.controller.start()
// Send data to server
// β οΈ Important: Audio must be mono PCM16 format matching configured sample rate
// audioData: ArrayBuffer or Uint8Array containing PCM16 audio samples
// - PCM files: Can be directly read as ArrayBuffer
// - WAV files: Extract PCM data from WAV format (may require resampling)
// - MP3 files: Decode first (e.g., using AudioContext.decodeAudioData()), then convert to PCM16
const audioData = new ArrayBuffer(1024) // Placeholder: Replace with actual PCM16 audio data
avatarView.controller.send(audioData, false) // Continue sending audio data
avatarView.controller.send(audioData, true) // end=true marks the end of conversation
// Interrupt conversation
avatarView.controller.interrupt()
// Close service
avatarView.controller.close()
avatarView.dispose()
})
// β οΈ CRITICAL: Initialize audio context first (MUST be called in user gesture context)
button.addEventListener('click', async () => {
// Initialize audio context - MUST be in user gesture context
await avatarView.controller.initializeAudioContext()
// Host Mode Workflow:
// Send audio data first to get conversationId, then use it to send animation data
// audioData: ArrayBuffer or Uint8Array containing PCM16 audio samples
// - PCM files: Can be directly read as ArrayBuffer
// - WAV files: Extract PCM data from WAV format (may require resampling)
// - MP3 files: Decode first (e.g., using AudioContext.decodeAudioData()), then convert to PCM16
const audioData = new ArrayBuffer(1024) // Placeholder: Replace with actual PCM16 audio data
const conversationId = avatarView.controller.yieldAudioData(audioData, false)
// Send animation data (requires conversationId from audio data)
const animationDataArray: (Uint8Array | ArrayBuffer)[] = [] // Animation keyframes binary data array
avatarView.controller.yieldFramesData(animationDataArray, conversationId)
// Interrupt conversation
avatarView.controller.interrupt()
// Clear all data and resources
avatarView.controller.clear()
avatarView.dispose()
})
Step 7: Debug & Run
- Open your application in a browser
- Check the browser console output to confirm SDK initialization succeeded
- Observe whether the avatar displays correctly
Itβs recommended to test in modern browsers (Chrome, Edge) for the best WebGPU support
Next Steps
π‘ Tip: For quick integration, please refer to the Demo Repository! The demo repository provides complete example code including full implementations for Vanilla, Vue, and React.