/ src / scripts / framework.ts
framework.ts
 1  /**
 2   * Injected script for detecting frontend frameworks (Vue, React, Next, Nuxt, etc.)
 3   *
 4   * Serialized via `.toString()` and evaluated in the page context. Types here are
 5   * only for the TS boundary — see scripts/store.ts for the same pattern.
 6   */
 7  
 8  interface VueAppEl {
 9    __vue__?: unknown;
10    __vue_app__?: {
11      config?: {
12        globalProperties?: { $pinia?: unknown; $store?: unknown };
13      };
14    };
15  }
16  interface FrameworkWindow extends Window {
17    __REACT_DEVTOOLS_GLOBAL_HOOK__?: unknown;
18    __NEXT_DATA__?: unknown;
19    __NUXT__?: unknown;
20  }
21  
22  export function detectFramework() {
23    const r: Record<string, boolean> = {};
24    try {
25      const app = document.querySelector('#app') as unknown as VueAppEl | null;
26      const w = window as FrameworkWindow;
27      r.vue3 = !!(app && app.__vue_app__);
28      r.vue2 = !!(app && app.__vue__);
29      r.react = !!w.__REACT_DEVTOOLS_GLOBAL_HOOK__ || !!document.querySelector('[data-reactroot]');
30      r.nextjs = !!w.__NEXT_DATA__;
31      r.nuxt = !!w.__NUXT__;
32      if (r.vue3 && app?.__vue_app__) {
33        const gp = app.__vue_app__.config?.globalProperties;
34        r.pinia = !!(gp && gp.$pinia);
35        r.vuex = !!(gp && gp.$store);
36      }
37    } catch {}
38    return r;
39  }