Icons
The browser never asks a third party for an icon, so a Content-Security-Policy needs no exception for the Iconify API. Icons reach the page two ways.
- Bundled. Nuxt UI's client bundle holds every icon its scanner finds in the workspace's Vue, Markdown and YAML files, the TypeScript of each layer's
app/directory,app.config.tsand itsui.iconsmappings included, and Nuxt UI's own defaults. - Served. Any other icon, such as a page icon a backend module declares, comes from the frontend server itself:
GET /api/_dms/icons/<prefix>.json?icons=<name>,…answers in the Iconify API format from the collections installed in the workspace.ajs dms devandajs dms startrun the same server, so both serve the route.
$ curl -sI "http://localhost:3005/api/_dms/icons/lucide.json?icons=house" | grep -iE "^HTTP|content-type|cache-control"
HTTP/1.1 200 OK
content-type: application/json
cache-control: public, max-age=604800, stale-while-revalidate=86400
Collections
The workspace ships @iconify-json/lucide and @iconify-json/ph. A module that uses another collection depends on its @iconify-json/<prefix> package, or on @iconify/json. An unknown collection answers 404, and a name outside Iconify's naming rule 400.
Server rendering
The server render draws every icon, bundled or not. The frontend server loads each installed @iconify-json/* collection once and hands it to the renderer, so an icon is drawn in its first render as soon as its data is loaded, instead of after the component mounts. The data of each icon a render drew travels in the page, so the browser draws the same icons as it hydrates. An icon no installed collection holds stays empty on the server and is fetched in the browser.
One sprite per page
Each icon is drawn once per page. A hidden <svg id="dms-icon-sprite"> holds one <symbol> per icon, and per flip or rotation, and every occurrence is an <svg> with a <use> of it, so an icon repeated on each row of a table is sent once. The browser draws the same way, adding the symbols of the icons it draws later to the same sprite.
Data loading
useDmsAsyncData, useDmsFetch, useDmsPagedData and useDmsState, how a server render waits for and transfers their data, and how the browser revalidates it.
Production
Build and serve the dashboard for real traffic, with the secrets it needs, behind a TLS reverse proxy, and how to scale it out.