Skip to content

Instantly share code, notes, and snippets.

@avallete
Created May 19, 2022 21:57
Show Gist options
  • Select an option

  • Save avallete/d01d704a1b5e3094943d93b95b7ac946 to your computer and use it in GitHub Desktop.

Select an option

Save avallete/d01d704a1b5e3094943d93b95b7ac946 to your computer and use it in GitHub Desktop.
Minimal Ybug React integration
import * as React from "react";
import { env } from "~/config/env";
const YBUG_SCRIPT_URL = `https://widget.ybug.io/button/${env.VITE_YBUG_ID}.js`;
const YbugContext = React.createContext<YbugApi | null>(null);
type YbugApi = {
boot: () => void;
show: (opt?: "launcher") => void;
open: (opt?: "annotate" | "feedback") => void;
destroy: () => void;
setUser: (infos: {
id: string;
name: string;
email: string;
phone?: string | null;
}) => void;
close: () => void;
};
type YbugSettings = {
id: string;
feedback?: {
comment?: string;
rating?: number;
email?: string;
name?: string;
};
anonymize_elements?: string;
language_override?: string;
launcher_position?:
| "bottom-left"
| "bottom-right"
| "left-middle"
| "right-middle"
| "top-middle";
widget_position?: "center" | "left" | "right";
skip_to?: "feedback";
hide_launcher?: boolean;
console_log?: boolean;
rating?: boolean; // Rating is disabled by default
rating_required?: boolean;
comment?: boolean; // Comment is enabled and required
comment_required?: boolean;
name?: boolean; // Name field is disabled
name_required?: boolean;
email?: boolean; // Email field is enabled and optional
email_required?: boolean;
type?: boolean; // Feedback type (Bug, Improvement, Question, ...)
type_required?: boolean;
title?: boolean; // Feedback title/summary field
title_required?: boolean;
priority?: boolean; // Feedback priority
priority_required?: boolean;
phone?: boolean; // Phone number field
phone_required?: boolean;
nps?: boolean; // Net Promoter Score® field
nps_required?: boolean;
close_countdown?: number;
shortcut?: boolean;
onload: () => unknown;
onopen: () => unknown;
onbeforesend: () => unknown;
oncancel: () => unknown;
onclose: () => unknown;
};
type YbugProviderProps = {
children: React.ReactNode;
settings?: YbugSettings & { [key: string]: string };
};
function useUsersnapApi() {
return React.useContext(YbugContext);
}
function YbugProvider({ children, settings }: YbugProviderProps) {
const [ybugApi, setYbugApi] = React.useState<YbugApi | null>(null);
React.useEffect(() => {
// @ts-expect-error will not be defined in window
window.ybug_settings = {
...settings,
id: env.VITE_YBUG_ID,
onload: () => {
// @ts-expect-error will not be defined in window
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
setYbugApi(window.Ybug);
settings?.onload?.();
},
};
const script = document.createElement("script");
script.defer = true;
script.src = `${env.VITE_TWICPICS_CLOVIS_CDN}${YBUG_SCRIPT_URL}`;
document.head.appendChild(script);
return () => {
if (ybugApi) {
ybugApi.destroy();
}
script.remove();
};
}, []);
return (
<YbugContext.Provider value={ybugApi}>{children}</YbugContext.Provider>
);
}
export type { YbugApi, YbugSettings };
export { useUsersnapApi, YbugProvider };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment