React
Basic Integration
Copy
import { useEffect } from 'react';
export default function ChatWidget() {
useEffect(() => {
const script = document.createElement('script');
script.src = 'https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js';
script.onload = () => {
window.LuaPop?.init({
agentId: "your-agent-id",
position: "bottom-right"
});
};
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
};
}, []);
return null;
}
With Environment Variables
Copy
// components/ChatWidget.tsx
import { useEffect } from 'react';
export default function ChatWidget() {
useEffect(() => {
const script = document.createElement('script');
script.src = 'https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js';
script.onload = () => {
window.LuaPop?.init({
agentId: process.env.REACT_APP_AGENT_ID,
environment: process.env.NODE_ENV === 'production' ? 'production' : 'staging',
position: "bottom-right",
sessionId: `user-${Date.now()}`
});
};
document.body.appendChild(script);
}, []);
return null;
}
Next.js
App Router
Copy
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script
src="https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js"
strategy="lazyOnload"
onLoad={() => {
window.LuaPop?.init({
agentId: process.env.NEXT_PUBLIC_AGENT_ID,
environment: process.env.NODE_ENV === 'production' ? 'production' : 'staging',
position: "bottom-right"
});
}}
/>
</body>
</html>
);
}
Pages Router
Copy
// pages/_app.tsx
import Script from 'next/script';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<Script
src="https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js"
strategy="lazyOnload"
onLoad={() => {
window.LuaPop?.init({
agentId: process.env.NEXT_PUBLIC_AGENT_ID,
position: "bottom-right"
});
}}
/>
</>
);
}
Vue.js
Vue 3
Copy
<template>
<div>
<!-- Your app content -->
</div>
</template>
<script setup>
import { onMounted } from 'vue';
onMounted(() => {
const script = document.createElement('script');
script.src = 'https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js';
script.onload = () => {
window.LuaPop?.init({
agentId: import.meta.env.VITE_AGENT_ID,
position: "bottom-right"
});
};
document.body.appendChild(script);
});
</script>
Nuxt.js
Copy
<!-- plugins/luapop.client.ts -->
export default defineNuxtPlugin(() => {
if (process.client) {
const script = document.createElement('script');
script.src = 'https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js';
script.onload = () => {
window.LuaPop?.init({
agentId: useRuntimeConfig().public.agentId,
position: "bottom-right"
});
};
document.body.appendChild(script);
}
});
Angular
Copy
// app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<router-outlet></router-outlet>
`
})
export class AppComponent implements OnInit {
ngOnInit() {
const script = document.createElement('script');
script.src = 'https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js';
script.onload = () => {
(window as any).LuaPop?.init({
agentId: environment.agentId,
position: "bottom-right"
});
};
document.body.appendChild(script);
}
}
Svelte
Copy
<!-- ChatWidget.svelte -->
<script>
import { onMount } from 'svelte';
onMount(() => {
const script = document.createElement('script');
script.src = 'https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js';
script.onload = () => {
window.LuaPop?.init({
agentId: import.meta.env.VITE_AGENT_ID,
position: "bottom-right"
});
};
document.body.appendChild(script);
});
</script>
WordPress
Using Theme Editor
Copy
<!-- Add to footer.php before </body> -->
<script src="https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js"></script>
<script>
window.LuaPop.init({
agentId: "<?php echo get_option('luapop_agent_id', 'your-agent-id'); ?>",
position: "bottom-right",
chatTitle: "<?php bloginfo('name'); ?> Support"
});
</script>
Using Plugin (Recommended)
Install plugin like “Insert Headers and Footers” or “Code Snippets” and add the LuaPop initialization code to the footer.Shopify
Copy
<!-- Add to theme.liquid before </body> -->
<script src="https://lua-ai-global.github.io/lua-pop/lua-pop.umd.js"></script>
<script>
window.LuaPop.init({
agentId: "{{ settings.luapop_agent_id }}",
chatTitle: "{{ shop.name }} Assistant",
buttonText: "🛍️ Shop Help",
position: "bottom-right",
{% if customer %}
sessionId: "customer-{{ customer.id }}",
runtimeContext: "customer:{{ customer.email }}"
{% endif %}
});
</script>
TypeScript Support
Copy
declare global {
interface Window {
LuaPop: {
init: (config: LuaPopConfig) => { destroy: () => void };
config?: LuaPopConfig;
};
}
}
interface LuaPopConfig {
agentId: string;
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
buttonText?: string;
buttonColor?: string;
environment?: "staging" | "production" | "custom";
sessionId?: string;
authToken?: string;
displayMode?: "floating" | "embedded";
voiceModeEnabled?: boolean;
welcomeMessage?: string;
chatInputPlaceholder?: string;
chatTitle?: string;
onNavigate?: (pathname: string, options: { query: Record<string, string> }) => void;
// ... other options
}
// Usage with type safety
window.LuaPop.init({
agentId: "your-agent-id",
position: "bottom-right" // TypeScript autocomplete works!
});
Best Practices
Use Environment Variables
Use Environment Variables
Copy
// ✅ Good
agentId: process.env.REACT_APP_AGENT_ID
// ❌ Bad
agentId: "hardcoded-id"
Cleanup in useEffect
Cleanup in useEffect
Copy
useEffect(() => {
// Load script
const script = document.createElement('script');
document.body.appendChild(script);
// Cleanup
return () => {
document.body.removeChild(script);
};
}, []);
Handle SSR
Handle SSR
Copy
// Next.js - only run on client
useEffect(() => {
if (typeof window !== 'undefined') {
// Load LuaPop
}
}, []);

