Rezept

Next.js App Router mit Server Components

Rendere Icons in Server Components ganz ohne JavaScript und greife nur dort zu Client-Komponenten, wo ein Icon auf Klicks reagiert oder sich zwischen Namen verwandelt.

Server Components

app/page.tsx
import { Icon, Fusion } from 'glyphfox/react/server';

export default function Page() {
  return (
    <main>
      <h1>
        <Icon name="home" size={28} className="title-icon" /> Dashboard
      </h1>
      <Icon name="file+check@tr" variant="duotone" title="Saved" />
      <Icon name="bell" animate="shake" trigger="hover" />
      <Icon name="menu" morphTo="x" trigger="hover" />
      <Fusion icons={['cloud', 'lock']} layout="overlap" />
    </main>
  );
}

glyphfox/react/server exportiert hook-freie Komponenten Icon und Fusion. Sie rendern beim Server-Rendering statisches SVG, dafür wird also nichts an den Browser geschickt, und jedes Icon des Sets ist per Namen verfügbar. Lebendige Zustände sowie Hover- und Zustands-Morphing reisen als CSS im SVG mit.

Client-Komponenten

app/like-button.tsx
'use client';

import { useState } from 'react';
import { HeartIcon, MorphIcon } from 'glyphfox/react';

export function LikeButton() {
  const [liked, setLiked] = useState(false);
  return (
    <button onClick={() => setLiked(!liked)} aria-pressed={liked}>
      <HeartIcon animate="pop" trigger="state" active={liked} variant={liked ? 'solid' : 'outline'} />
      <MorphIcon name={liked ? 'check' : 'heart'} />
    </button>
  );
}

Die Module von glyphfox/react sind mit 'use client' markiert, daher funktionieren die Icon-Komponenten auch, wenn eine Server Component sie direkt rendert: Sie werden auf dem Server gerendert und hydriert. Nutze sie dort, wo du den Klick-Trigger, Morph-Übergänge oder useMorph brauchst.

Bundle-Größe

next.config.mjs
/** @type {import('next').NextConfig} */
export default {
  experimental: {
    optimizePackageImports: ['glyphfox'],
  },
};

Jedes Icon ist ein eigenes Modul. Mit optimizePackageImports schreibt Next.js Barrel-Imports auf diese Module um; Deep Imports wie import { FileIcon } from 'glyphfox/react/icons/file' funktionieren überall ohne Konfiguration.

Sprite

Terminal
npx glyphfox build home search file+check --type sprite --out public/icons
app/nav.tsx
export function SpriteGlyph({ name }: { name: string }) {
  return (
    <svg width="20" height="20" aria-hidden="true">
      <use href={`/icons/sprite.svg#gf-${name}`} />
    </svg>
  );
}

Für lange Listen statischer Icons hält ein Sprite mit nur den Icons, die du nutzt, das HTML klein und bleibt über Seiten hinweg im Cache.