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 }