Framework Guides

Integration patterns for React, Next.js, and Vue. VoiceLayer works with any framework — these are the recommended patterns.

React
Next.js
Vue

React hook

Create a useVoiceLayer hook that initializes the SDK and cleans up on unmount:

// hooks/useVoiceLayer.ts
import { useEffect } from 'react';
import { VoiceLayer } from '@voicelayer/sdk';

export function useVoiceLayer(apiKey: string) {
  useEffect(() => {
    const vl = VoiceLayer.init({ apiKey, showBranding: false });
    return () => vl.destroy();
  }, [apiKey]);
}

Use it in your root component or layout:

// App.tsx
import { useVoiceLayer } from './hooks/useVoiceLayer';

export default function App() {
  useVoiceLayer(process.env.REACT_APP_VOICELAYER_KEY!);

  return (
    <div>
      {/* Every input in your app now has voice input */}
      <input placeholder="Type or hold Space to speak" />
      <textarea placeholder="Voice works here too" />
    </div>
  );
}

Scoped activation

To activate only specific inputs, pass a CSS selector:

VoiceLayer.init({
  apiKey: 'pk_live_...',
  selector: '[data-voice]',  // only inputs with data-voice attribute
});

// In your JSX:
<textarea data-voice placeholder="Voice-enabled" />
<input data-voice type="text" />
<input type="text" /> {/* NOT activated */}

Client component

Create a client-only provider component — VoiceLayer requires browser APIs:

// components/VoiceProvider.tsx
'use client';

import { useEffect } from 'react';
import { VoiceLayer } from '@voicelayer/sdk';

export function VoiceProvider() {
  useEffect(() => {
    const vl = VoiceLayer.init({
      apiKey: process.env.NEXT_PUBLIC_VOICELAYER_KEY!,
      showBranding: false,
    });
    return () => vl.destroy();
  }, []);

  return null;
}

Add it to your root layout:

// app/layout.tsx
import { VoiceProvider } from '@/components/VoiceProvider';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <VoiceProvider />
        {children}
      </body>
    </html>
  );
}

Environment variable

# .env.local
NEXT_PUBLIC_VOICELAYER_KEY=pk_live_YOUR_KEY

Vue composable

// composables/useVoiceLayer.js
import { onMounted, onUnmounted } from 'vue';
import { VoiceLayer } from '@voicelayer/sdk';

export function useVoiceLayer(apiKey) {
  let vl;

  onMounted(() => {
    vl = VoiceLayer.init({ apiKey, showBranding: false });
  });

  onUnmounted(() => {
    vl?.destroy();
  });
}

Use in your root App component:

<!-- App.vue -->
<script setup>
import { useVoiceLayer } from './composables/useVoiceLayer';
useVoiceLayer(import.meta.env.VITE_VOICELAYER_KEY);
</script>

<template>
  <RouterView />
</template>
# .env
VITE_VOICELAYER_KEY=pk_live_YOUR_KEY

Transcript handling

In all frameworks, use the onTranscript callback to intercept or modify transcripts before they're injected:

VoiceLayer.init({
  apiKey: 'pk_live_...',
  onTranscript: (text) => {
    // Send to analytics
    analytics.track('voice_input', { length: text.length });

    // Auto-capitalize
    return text.charAt(0).toUpperCase() + text.slice(1);
  },
});