Ir al contenido

React

El SDK es una librería de navegador: depende de window y document, y monta su propio contenedor en document.body. Funciona sin configuración adicional en cualquier app React que se ejecute en el navegador (Vite, CRA, Next.js, Remix, etc.).

En frameworks con SSR (Next.js App Router, Remix), asegúrate de instanciar el SDK únicamente en el cliente — normalmente dentro de un useEffect o de un componente con 'use client'.

Ventana de terminal
npm install @magicfeedback/popup-sdk

El SDK guarda estado interno y debe crearse una sola vez por aplicación. La forma más limpia es envolverlo en un hook y llamarlo desde el layout raíz o un provider de alto nivel.

hooks/useDeepdotsPopups.ts
import { useEffect, useRef } from 'react';
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';
export function useDeepdotsPopups(userId?: string) {
const ref = useRef<DeepdotsPopups | null>(null);
useEffect(() => {
if (ref.current) return;
const popups = new DeepdotsPopups();
popups.init({
mode: 'server',
apiKey: 'YOUR_PUBLIC_API_KEY',
userId,
});
popups.autoLaunch();
ref.current = popups;
}, [userId]);
return ref;
}
App.tsx
import { useDeepdotsPopups } from './hooks/useDeepdotsPopups';
export default function App() {
useDeepdotsPopups('customer-123');
return <YourRoutes />;
}

En el App Router, monta el SDK dentro de un componente cliente e impórtalo desde el layout raíz.

app/components/DeepdotsProvider.tsx
'use client';
import { useEffect } from 'react';
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';
export function DeepdotsProvider({ userId }: { userId?: string }) {
useEffect(() => {
const popups = new DeepdotsPopups();
popups.init({
mode: 'server',
apiKey: process.env.NEXT_PUBLIC_DEEPDOTS_API_KEY!,
userId,
});
popups.autoLaunch();
}, [userId]);
return null;
}
app/layout.tsx
import { DeepdotsProvider } from './components/DeepdotsProvider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="es">
<body>
{children}
<DeepdotsProvider userId="customer-123" />
</body>
</html>
);
}

También puedes guardar una referencia a la instancia y llamar a show() o triggerEvent() desde un handler.

'use client';
import { useEffect, useRef } from 'react';
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';
export function FeedbackButton() {
const popupsRef = useRef<DeepdotsPopups | null>(null);
useEffect(() => {
const popups = new DeepdotsPopups();
popups.init({
mode: 'server',
apiKey: 'YOUR_PUBLIC_API_KEY',
});
popups.autoLaunch();
popupsRef.current = popups;
}, []);
return (
<button
onClick={() =>
popupsRef.current?.show({
surveyId: 'survey-home-001',
productId: 'product-main',
})
}
>
Enviar feedback
</button>
);
}

Suscríbete dentro de useEffect y cancela la suscripción en el cleanup para evitar fugas entre re-montajes (por ejemplo, con React StrictMode en desarrollo).

useEffect(() => {
const popups = new DeepdotsPopups();
popups.init({ mode: 'server', apiKey: 'YOUR_PUBLIC_API_KEY' });
const onShown = (event: unknown) => console.log('shown', event);
const onCompleted = (event: unknown) => console.log('completed', event);
popups.on('popup_shown', onShown);
popups.on('survey_completed', onCompleted);
popups.autoLaunch();
return () => {
popups.off('popup_shown', onShown);
popups.off('survey_completed', onCompleted);
};
}, []);