Icons
Lattice renders icons from a single SVG sprite built at your app’s Vite step. Components reference an icon by name (a string that comes from the server), and the sprite resolves it at render time — so adding an icon is just dropping an SVG in a folder, with no per-icon imports.
The sprite is produced by Lattice’s Vite helper, which wraps
@lattice-php/vite-svg-sprite and merges Lattice’s
built-in icons with your own into one cached file.
Add Lattice’s helper to vite.config.ts. The helper includes Lattice’s icons automatically. Later
directories win on name collisions, so resources/icons can override a built-in icon.
import { lattice } from "@lattice-php/lattice/vite";
export default defineConfig({ plugins: [ lattice({ icons: { dirs: ["resources/icons"], }, }), laravel({ /* ... */ }), // ... ],});Then pass the sprite into Lattice’s Provider:
/// <reference types="@lattice-php/lattice/svg-sprite-client" />import sprite from "virtual:svg-sprite";import { Provider, registry } from "@lattice-php/lattice";
createInertiaApp({ setup({ el, App, props }) { createRoot(el).render( <Provider registry={registry} sprite={sprite}> <App {...props} /> </Provider>, ); },});In production the sprite is emitted as a hashed asset and referenced with <use href>; in dev it’s
inlined into the page, so it works regardless of where the page is served from.
Adding icons
Section titled “Adding icons”Drop any SVG into a folder the plugin scans (e.g. resources/icons/spark.svg) and reference it by its
filename:
MenuItem::make('Spark')->icon('spark');Icons inherit their colour via currentColor and their size via the size-* utility on the element,
so a single SVG adapts to wherever it’s used. To pull icons from a package instead of downloading them
by hand, vendor them.
Vendoring icons from a package
Section titled “Vendoring icons from a package”Rather than hand-download SVGs, you can vendor a named set from an icon package: the plugin copies
just the icons you list into your project and commits them. You ship only the icons you use — not a
whole library — and the set is reproducible from the config. This is how Lattice sources its own icons
from lucide-static.
Install the source package as a dev dependency:
npm install -D lucide-staticThen list the icons you want under include:
lattice({ icons: { dirs: ["resources/icons"], include: [ { from: "lucide-static/icons", // a package's icon folder, or any local directory names: ["rocket", "sparkles", "wand-sparkles"], outDir: "resources/icons/lucide", }, ], },});Each build copies rocket.svg, sparkles.svg, and wand-sparkles.svg out of the package into
resources/icons/lucide and folds them into the sprite. Reference them by name like any other icon:
MenuItem::make('Launch')->icon('rocket');from— a folder of SVGs: a package’s icon directory resolved fromnode_modules(e.g.lucide-static/icons), or a path to a local directory.names— the filenames to copy, without.svg. A name missing from the source fails the build, so a typo surfaces immediately.outDir— where the SVGs are written. It joins the sprite automatically; you don’t also list it underdirs.
The copy is idempotent: it writes only files whose content changed, so re-running the build is a no-op once synced, and it never touches anything else in the folder — vendored and hand-authored icons can share a directory. Commit the copied SVGs; the source package is then only needed at build time, so anyone installing your package gets the icons without it.
Referencing icons
Section titled “Referencing icons”Anywhere a component takes an icon you can pass a plain string or a backed enum:
use Lattice\Lattice\Core\Enums\Icon;
// by nameAction::make('app.send')->icon('send');
// or via the curated enum of Lattice's built-in iconsAction::make('app.send')->icon(Icon::Send);Lattice\Lattice\Core\Enums\Icon covers Lattice’s own icon set. For your full set (Lattice’s plus your
own), generate an enum — see below.
As a component
Section titled “As a component”Icon is also a component, so a standalone icon can go anywhere in a schema. It renders through the
same renderer as ->icon(), with structured size/color plus a raw class escape hatch:
use Lattice\Lattice\Core\Components\Icon;use Lattice\Lattice\Core\Enums\Color;use Lattice\Lattice\Core\Enums\Size;
Stack::make()->schema([ Icon::make('house'), // size defaults to Md Icon::make('circle-check')->size(Size::Lg)->color(Color::Success), Icon::make('spark')->class('opacity-70'),]);size defaults to Size::Md; color is optional and inherits currentColor when unset. Sizes resolve
to themeable tokens (--lt-icon-xs … --lt-icon-xl).
Type-safe icon names
Section titled “Type-safe icon names”The plugin can generate a type module and/or a PHP enum from the built sprite, so icon names stay autocompletable. Both files are committed and regenerated idempotently on each build.
TypeScript — Lattice emits resources/js/types/sprite-icons.ts by default. Override dts when you
want a different generated file:
lattice({ icons: { dirs: ["resources/icons"], dts: { file: "resources/js/sprite-icons.ts", augmentModule: "@lattice-php/lattice", augmentInterface: "KnownIcons", }, },});PHP — phpEnum emits a backed enum covering your full sprite:
lattice({ icons: { dirs: ["resources/icons"], phpEnum: { file: "app/Support/Icon.php", namespace: "App\\Support", enum: "Icon" }, },});use App\Support\Icon;
MenuItem::make('Home')->icon(Icon::House);Re-run the build (or dev server) after adding icons to refresh the generated files.
Custom rendering
Section titled “Custom rendering”Server-driven icons resolve through a stack of renderer functions, so you can override how a name
renders — for example to pull from an icon-component library — by wrapping part of the tree in
IconRendererProvider:
import { IconRendererProvider } from "@lattice-php/lattice";
<IconRendererProvider renderer={({ icon, className }) => /* a node, or null to fall through */}> <App /></IconRendererProvider>;A renderer that returns null falls through to the next one, ending at the sprite. This is rarely
needed — dropping an SVG in a folder is the usual path.