Ctrl K
ComunidadGuías…

plugins/analytics-tracking.client.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
export default defineNuxtPlugin(() => {
  const track = (el: HTMLElement) => {
    const eventName = el.dataset.gaEvent;
    if (!eventName) return;
    const value = el.dataset.gaValue;
    trackEvent(eventName, value !== undefined ? { value } : undefined);
  };

  // Text-like inputs are tracked via the keydown(Enter) listener below, not
  // click — clicking one just focuses it, it doesn't confirm anything.
  // Checkboxes/radios are the exception: a click on them *is* the value
  // change, so they're tracked here.
  const isTextlikeInput = (el: HTMLElement) =>
    el.tagName === 'INPUT' && !['checkbox', 'radio'].includes((el as HTMLInputElement).type);

  // Capture phase: several components call @click.stop, which calls
  // stopPropagation() during the bubble phase and would prevent a
  // bubble-phase listener on document from ever seeing the click.
  document.addEventListener('click', (e) => {
    const el = (e.target as HTMLElement)?.closest<HTMLElement>('[data-ga-event]');
    if (el && !isTextlikeInput(el)) track(el);
  }, true);

  document.addEventListener('keydown', (e) => {
    if (e.key !== 'Enter') return;
    const el = (e.target as HTMLElement)?.closest<HTMLElement>('input[data-ga-event]');
    if (el) track(el);
  }, true);

  // Separate attribute (not data-ga-event) for inputs that commit their value
  // on native 'change' (blur-after-edit) rather than via a Submit/Enter
  // action — using the same attribute here would misfire on plain blur for
  // inputs like folder-rename/tag-form that only confirm via Enter/button.
  document.addEventListener('change', (e) => {
    const el = (e.target as HTMLElement)?.closest<HTMLElement>('[data-ga-event-on-change]');
    const eventName = el?.dataset.gaEventOnChange;
    if (eventName) trackEvent(eventName);
  }, true);

  // Note content editing fires 'input' on every keystroke across all 3
  // editors (Tiptap/CodeMirror/Crepe) — debounce to one event per burst of
  // typing instead of tracking each keystroke.
  const EDITOR_SELECTOR = '#tiptap-editor, #cm-editor, #crepe-editor';
  let editContentTimer: ReturnType<typeof setTimeout> | undefined;
  document.addEventListener('input', (e) => {
    const el = (e.target as HTMLElement)?.closest<HTMLElement>(EDITOR_SELECTOR);
    if (!el) return;
    clearTimeout(editContentTimer);
    editContentTimer = setTimeout(() => trackEvent('note_edit_content'), 1500);
  }, true);
});