Quickstart Guide

the XiixBlocks template

  1. Step One: Install starter dependencies and run
npm install
npm run dev
  1. Step Two: Configure your assistant using enviornment variables

Edit the .env file with Public Key and Assistant ID. You can configure your assistant and get these values from the Dashboard.

NEXT_PUBLIC_xiix_PUBLIC_KEY=""
NEXT_PUBLIC_xiix_ASSISTANT_ID=""

Manual Setup

npx create-next-app@latest

After running the command, you will be prompted with a series of questions, this is where you can configure your project to use xiix Blocks with NextJS and Tailwind CSS.

What is your project named? your-project-name
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like to use `src/` directory? No
Would you like to use App Router? Yes
Would you like to customize the default import alias No

npm install @ai/react

Lastly, copy over the use-vapi hook to your "hooks" folder (if using Next.js). If using Vanilla React, Vue or alternative framework copy over to "lib" or similar folder.

//hooks/use.ts
import { useEffect, useRef, useState, useCallback } from 'react';
import ai from '@ai/web';
 
const publicKey = process.env.xiix_PUBLIC_KEY; // Replace with your actual public key
const assistantId = process.env.xiix_ASSISTANT_ID; // Replace with your actual assistant ID
 
const use = () => {
  const [volumeLevel, setVolumeLevel] = useState(0);
  const [isSessionActive, setIsSessionActive] = useState(false);
  const [conversation, setConversation] = useState<{ role: string, text: string }[]>([]);
  const vapiRef = useRef<any>(null);
 
  const initialize = useCallback(() => {
    if (!Ref.current) {
      const Instance = new (publicKey);
      Ref.current = Instance;
 
      Instance.on('call-start', () => {
        setIsSessionActive(true);
      });
 
      Instance.on('call-end', () => {
        setIsSessionActive(false);
        setConversation([]); // Reset conversation on call end
      });
 
      Instance.on('volume-level', (volume: number) => {
        setVolumeLevel(volume);
      });
 
      Instance.on('message', (message: any) => {
        if (message.type === 'transcript' && message.transcriptType === 'final') {
          setConversation((prev) => [
            ...prev,
            { role: message.role, text: message.transcript },
          ]);
        }
      });
 
      Instance.on('error', (e: Error) => {
        console.error(' error:', e);
      });
    }
  }, []);
 
  useEffect(() => {
    initialize();
 
    // Cleanup function to end call and dispose instance
    return () => {
      if (Ref.current) {
        Ref.current.stop();
        Ref.current = null;
      }
    };
  }, [initialize]);
 
  const toggleCall = async () => {
    try {
      if (isSessionActive) {
        await Ref.current.stop();
      } else {
        await Ref.current.start(assistantId);
      }
    } catch (err) {
      console.error('Error toggling session:', err);
    }
  };
 
  return { volumeLevel, isSessionActive, conversation, toggleCall };
};
 
export default use;
 

This hook can be extended with advanced function-calling and more.