The Usersnap alternative.
Give customer reports a path to a fix. Capture the problem inside your app and keep the customer in the conversation. Gleap connects visual reports to support, investigation and engineering work your team reviews.
Give customer reports a path to a fix. Capture the problem inside your app and keep the customer in the conversation. Gleap connects visual reports to support, investigation and engineering work your team reviews.
applyCoupon resets the cart before POST /orders/confirm, so the request fails with cart_expired.
sendSurveyPush returns early without a contact email. Delivery only needs the session's subscription.
Answer customers. Investigate issues. Build what comes next. Kai is available on every plan; Resolve, Code and PM are included in Pro and Enterprise. AI usage is billed separately.
Answers customers
Answers from your knowledge base and connected sources. Brings your team in when needed.
Investigates hard tickets
Reads session evidence, logs and code. Returns findings and creates coding tasks for confirmed bugs.
Builds the fix
Plans the change, writes and tests code, and opens a pull request. Your engineers review and merge.
Prioritizes requests
Triages feedback, finds duplicates and scores requests. You decide what belongs on the roadmap.
applyCoupon resets the cart before POST /orders/confirm, so the request fails with cart_expired.
sendSurveyPush returns early without a contact email. Delivery only needs the session's subscription.
@@ -42,7 +42,15 @@ NotificationsDrawer const { items } = useNotifications();− useEffect(() => { if (open) refetch(); });+ const socket = useNotificationSocket();+ useEffect(() => {+ if (!open) return;+ return socket.on('notification:new',+ (n) => setItems((p) => [n, ...p]));+ }, [open, socket]); return <Drawer open={open}>
@@ -8,6 +8,18 @@ useNotificationSocket const socket = useSocket();+ const on = useCallback((evt, fn) => {+ socket.on(evt, fn);+ return () => socket.off(evt, fn);+ }, [socket]);− return socket;+ return { on };
@@ -0,0 +1,4 @@+ it('appends a pushed notification',+ async () => {+ render(<NotificationsDrawer open />);+ socket.emit('notification:new', n);+ expect(await findByText(n.title))+ .toBeVisible();