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>
This commit is contained in:
2026-05-12 07:45:50 +02:00
parent 29f3fdf2a3
commit b1443be414
2 changed files with 30 additions and 0 deletions

View File

@@ -1,3 +1,9 @@
// 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 { createApp } from 'vue'
import { VueQueryPlugin } from '@tanstack/vue-query' import { VueQueryPlugin } from '@tanstack/vue-query'
import { queryClientConfig } from '@/lib/query-client' import { queryClientConfig } from '@/lib/query-client'

View File

@@ -0,0 +1,24 @@
// Iconify-Tabler runtime bootstrap — introduced in F3.5 to make
// @iconify/vue's <Icon> render real SVG paths from local data instead
// of fetching individual icons from https://api.iconify.design/ at
// runtime. The CSP blocks that origin, so the previous behaviour was
// an empty <svg viewBox="0 0 16 16"></svg> for every Tabler icon used
// in the PrimeVue side of the parallel-mode app.
//
// This file is a separate concern from src/plugins/iconify/index.ts +
// icons.css, which exists to serve the Vuetify side: Vuexy's @core
// `<VIcon icon="tabler-X" />` adapter renders via the i-tabler-* CSS
// classes those files inject, and Vuetify never touches the @iconify
// /vue runtime. The two systems must coexist until F6 retires
// Vuetify, after which the legacy plugins/iconify/ directory can be
// deleted alongside it.
//
// Imported as a side effect at the top of main.ts, so addCollection
// runs before any component renders an Icon. The whole Tabler set
// (~1.9 MB uncompressed JSON / ~400 KB gzipped) is loaded eagerly;
// per-icon imports are a future optimisation, not in F3.5 scope.
import { addCollection } from '@iconify/vue'
import tablerIcons from '@iconify-json/tabler/icons.json'
addCollection(tablerIcons)