Files
crewli-old/apps/app/src/main.ts
bert.hausmans b1443be414 fix(iconify): bootstrap Tabler icon set at runtime for @iconify/vue
The PrimeVue side of the parallel-mode app renders icons via
@iconify/vue's <Icon> component (src/components/Icon.vue). At runtime
@iconify/vue resolves an icon name like "tabler-eye" by looking up
its data in the in-memory icon registry; on a miss it falls back to
fetching https://api.iconify.design/tabler/eye.json. The CSP blocks
that origin, so every Tabler icon used in AppShell, SidebarHeader,
SidebarUserCard, and the migrated login form rendered as an empty
<svg viewBox="0 0 16 16"></svg>.

New plugins/iconify.ts loads the full Tabler set
(@iconify-json/tabler/icons.json, already in package.json as 1.2.23)
and registers it via addCollection() at module-load time. main.ts
side-effect-imports it before any other import so the registry is
warm before the first Icon mounts.

This is a NEW concern, separate from the existing plugins/iconify/
(index.ts + icons.css) which generates Vuexy-style i-tabler-* CSS
classes for Vuetify's VIcon adapter. The two systems must coexist
during F3–F6 parallel mode; the legacy directory can be deleted
alongside Vuetify when F6 lands.

Bundle cost: ~1.9 MB uncompressed JSON, ~400 KB gzipped in the main
chunk. Per-icon imports are a future optimisation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 13:35:59 +02:00

52 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Iconify-Tabler runtime data — side-effect import must run before any
// component renders an Icon, so the @iconify/vue runtime resolves
// names locally instead of falling back to the api.iconify.design CDN
// (blocked by our CSP). See plugins/iconify.ts for the bootstrap.
import '@/plugins/iconify'
import { createApp } from 'vue'
import { VueQueryPlugin } from '@tanstack/vue-query'
import { queryClientConfig } from '@/lib/query-client'
import { initSentry, installContextBinding } from '@/observability'
import { router } from '@/plugins/1.router'
import App from '@/App.vue'
import { registerPlugins } from '@core/utils/plugins'
import installPrimeVue from '@/plugins/primevue'
// Styles
import '@styles/tailwind.css'
import '@core/scss/template/index.scss'
import '@styles/styles.scss'
// Create vue app
const app = createApp(App)
// RFC-WS-7 — Sentry init runs before plugin registration so the SDK can
// hook Vue's errorHandler before any plugin or component initialises.
// Empty DSN = SDK no-op (mirrors backend behaviour, RFC §3.3).
initSentry({
app,
router,
dsn: import.meta.env.VITE_SENTRY_DSN_FRONTEND ?? '',
release: import.meta.env.VITE_SENTRY_RELEASE ?? '',
environment: import.meta.env.MODE,
})
// Register plugins (router, pinia, vuetify, …).
registerPlugins(app)
// PrimeVue runs alongside Vuetify during the F3F6 parallel-mode window.
// Registered AFTER registerPlugins(app) so PrimeVue lives outside the
// Vuexy @core/ machine — F6 can remove @core/ without affecting PrimeVue.
installPrimeVue(app)
// Bind auth-scope tags per route navigation. Must run after pinia is set
// up by registerPlugins (the guard reads useAuthStore / useOrganisationStore).
installContextBinding(router)
app.use(VueQueryPlugin, queryClientConfig)
// Mount vue app
app.mount('#app')