Vite Integration
Integrate the Lingu widget into your Vite application (React, Vue, Svelte, or vanilla).
React + Vite
Using a Component
tsx
// src/components/LinguWidget.tsx
import { useEffect } from 'react';
interface LinguWidgetProps {
apiKey: string;
autoOpen?: boolean;
}
export function LinguWidget({ apiKey, autoOpen = false }: LinguWidgetProps) {
useEffect(() => {
// Set configuration
window.linguConfig = {
apiKey,
autoOpen
};
// Load widget script
const script = document.createElement('script');
script.src = 'https://widget.uselingu.app/widget.js';
script.async = true;
script.id = 'lingu-widget-script';
document.body.appendChild(script);
// Cleanup on unmount
return () => {
const existingScript = document.getElementById('lingu-widget-script');
if (existingScript) {
existingScript.remove();
}
const container = document.getElementById('lingu-widget-root');
if (container) {
container.remove();
}
};
}, [apiKey, autoOpen]);
return null;
}Usage in App
tsx
// src/App.tsx
import { LinguWidget } from './components/LinguWidget';
function App() {
return (
<div>
<h1>My Vite App</h1>
{/* Widget is available throughout the app */}
<LinguWidget
apiKey={import.meta.env.VITE_LINGU_API_KEY}
/>
</div>
);
}
export default App;Environment Variables
Create a .env file in your project root:
bash
# .env
VITE_LINGU_API_KEY=lingu_abc123def456Access it in your code:
tsx
const apiKey = import.meta.env.VITE_LINGU_API_KEY;TIP
Vite requires the VITE_ prefix to expose environment variables to the client.
TypeScript Support
Add type declarations for environment variables and global window:
typescript
// src/vite-env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_LINGU_API_KEY: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
interface Window {
linguConfig?: {
apiKey: string;
autoOpen?: boolean;
baseURL?: string;
};
LinguWidget?: any;
}Vue + Vite
Using a Composable
vue
<!-- src/components/LinguWidget.vue -->
<script setup lang="ts">
import { onMounted, onBeforeUnmount } from 'vue';
const props = defineProps<{
apiKey: string;
autoOpen?: boolean;
}>();
onMounted(() => {
// Set configuration
window.linguConfig = {
apiKey: props.apiKey,
autoOpen: props.autoOpen ?? false
};
// Load widget script
const script = document.createElement('script');
script.src = 'https://widget.uselingu.app/widget.js';
script.async = true;
script.id = 'lingu-widget-script';
document.body.appendChild(script);
});
onBeforeUnmount(() => {
const script = document.getElementById('lingu-widget-script');
if (script) script.remove();
const container = document.getElementById('lingu-widget-root');
if (container) container.remove();
});
</script>
<template>
<!-- Component renders nothing, widget injects itself -->
</template>Usage in App.vue
vue
<!-- src/App.vue -->
<script setup lang="ts">
import LinguWidget from './components/LinguWidget.vue';
</script>
<template>
<div>
<h1>My Vue App</h1>
<LinguWidget :api-key="import.meta.env.VITE_LINGU_API_KEY" />
</div>
</template>Vanilla Vite (No Framework)
For vanilla JavaScript/TypeScript Vite projects:
html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<!-- Lingu Widget -->
<script>
window.linguConfig = {
apiKey: 'your-api-key-here'
};
</script>
<script src="https://widget.uselingu.app/widget.js" defer></script>
</body>
</html>Dynamic Loading
Load the widget dynamically based on conditions:
typescript
// src/lib/lingu.ts
export async function loadLinguWidget(apiKey: string) {
return new Promise<void>((resolve, reject) => {
// Check if already loaded
if (document.getElementById('lingu-widget-script')) {
resolve();
return;
}
// Set config
window.linguConfig = { apiKey };
// Load script
const script = document.createElement('script');
script.id = 'lingu-widget-script';
script.src = 'https://widget.uselingu.app/widget.js';
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject(new Error('Failed to load Lingu widget'));
document.body.appendChild(script);
});
}
export function unloadLinguWidget() {
const script = document.getElementById('lingu-widget-script');
if (script) script.remove();
const container = document.getElementById('lingu-widget-root');
if (container) container.remove();
delete window.linguConfig;
}Usage
typescript
import { loadLinguWidget, unloadLinguWidget } from './lib/lingu';
// Load widget when user logs in
async function onLogin() {
await loadLinguWidget(import.meta.env.VITE_LINGU_API_KEY);
}
// Unload when user logs out
function onLogout() {
unloadLinguWidget();
}Build Considerations
The widget loads from an external CDN, so there's no need to bundle it with your Vite build. This keeps your bundle size small and ensures you always get the latest widget version.