Every Fontdue component that shows catalog data has to get that data somehow, and there are two ways it can arrive. Lazily: the component fetches its data in the browser after it appears, so there’s a brief gap before its content fills in. Preloaded: the data is already in place when the component first renders, so it comes in complete on the first paint, with no gap. It’s the same component and the same data either way – what differs is when the fetch happens, and so whether anyone watches it load. Which one you get comes down to the framework you picked – to how it server-renders – so what follows is the short version for yours, and the rest of the walkthrough builds on it.
Which one your framework uses
In the Next.js App Router, the difference is subtle. When components are rendered directly inside React Server Components they’re preloaded automatically11This works “magically” using Suspense-based data fetching with Relay.. When you place a Fontdue component inside a client tree (anything under a "use client" boundary) it loads lazily, fetching its own data in the browser after it mounts, and causing layout shifts. To get the data server-rendered, keep the component in a server component. Either way you place it with just its identifier:
In Next.js, pages are rendered server-side, and you can choose whether or not to preload their Fontdue components. If you pass in the props required for querying (e.g. collectionId or collectionSlug), the component will lazy-load after the initial page load, and cause the layout to shift. Avoid it by fetching the component’s data before the page renders: pass in a preloadedQuery prop, and the component arrives complete in the first paint.22A component takes a preloadedQuery or the query props that drive a lazy fetch, not both – most rule out the combination with their TypeScript types.
The call goes in the page’s frontmatter, before the markup renders.
The call goes in the route’s loader, which runs on the server before the component renders.
TanStack Start has its own experimental React Server Components mode, but Fontdue’s components don’t use it – preload through the route loader as above. An RSC entry point would be strictly more wiring than the preloaded path for no rendering gain, since preloading already server-renders with no flash.
<TypeTesters collectionSlug="example-serif" />
import TypeTesters, { loadTypeTestersQuery } from "fontdue-js/TypeTesters";
// in the page frontmatter
const typeTestersPreload = await loadTypeTestersQuery({ collectionSlug: "example-serif" });
// rendered as an island
<TypeTesters client:load preloadedQuery={typeTestersPreload} config={config} />
import TypeTesters, { loadTypeTestersQuery } from "fontdue-js/TypeTesters";
// in the route loader
const typeTestersPreload = await loadTypeTestersQuery({ collectionSlug: "example-serif" });
// in the component
<TypeTesters preloadedQuery={typeTestersPreload} />
import TypeTesters, { loadTypeTestersQuery } from "fontdue-js/TypeTesters";
// in the route loader
const typeTestersPreload = await loadTypeTestersQuery({ collectionSlug: "example-serif" });
// in the component
<TypeTesters preloadedQuery={typeTestersPreload} />
These examples all use TypeTesters, but the same pattern applies to every Fontdue component that reads your catalog – only the props change from one to the next. The component reference documents each one’s full API: the props it takes, the identifiers it accepts, and the data it renders.
Components with no data to wire
Three components never take an identifier or a preload, so neither path applies: the Store Modal, the Cart Button, and the Customer Login Form. What they show is per-session – the live cart, whether someone’s signed in – and that state lives only in the browser, so there’s nothing in your catalog to fetch ahead of time or on load. You place them with no id at all, and they read their session state in the browser.
With the data question settled, the next pages put it to work: querying your catalog with typed data, then building font pages that render a detail page per collection from it.