Skip to Content
API ReferenceNexusRenderer

NexusRenderer

NexusRenderer is a server-only component that can improve performance by delegating rendering to the client.

Core Concept: Rendering Delegation

When a user navigates between pages, they might already have fresh data for the next page in their client-side cache. In this scenario, having the server re-fetch and re-render the components is redundant work that increases Time to First Byte (TTFB) and server costs.

NexusRenderer solves this by checking the client’s cache state before rendering on the server. If it determines the client has fresh data for the required definition(s), it skips server-rendering the component and instead sends a lightweight placeholder, instructing the client to render it immediately using the cached data.

Import

import { NexusRenderer } from 'next-nexus/server';

How It Works

NexusRenderer relies on client cache metadata sent with RSC requests (see NexusRuntime). It compares the definition(s) you provide against this metadata to check for cache freshness (based on revalidate TTL).

  • If fresh: It delegates rendering to the client.
  • If stale or missing: It renders the serverComponent and triggers the necessary server-side nexus calls to hydrate the client.

Usage

You provide NexusRenderer with both a server and a client version of a component.

  • serverComponent: The component to render on the server if data is not fresh on the client.
  • clientComponent: The component to render on the client. This is often the same component as the server one, but re-exported from a 'use client' file.

With a Single Definition

// components/ProductListUI.tsx (can be a Server Component) import type { Product } from '@/api/productDefinition'; const ProductListUI = ({ data, title }: { data: Product[]; title: string }) => ( <div> <h2>{title}</h2> <ul>{data.map(p => <li key={p.id}>{p.name}</li>)}</ul> </div> ); export default ProductListUI; // components/client/ui.ts (re-export for client use) 'use client'; export { default as ProductListUIClient } from '@/components/ProductListUI'; // app/page.tsx (Server Component) import { NexusRenderer } from 'next-nexus/server'; import { productDefinition } from '@/api/productDefinition'; import ProductListUI from '@/components/ProductListUI'; import { ProductListUIClient } from '@/components/client/ui'; export default function Page() { return ( <NexusRenderer definition={productDefinition.list} serverComponent={ProductListUI} clientComponent={ProductListUIClient} componentProps={{ title: 'Our Products' }} /> ); }

With a Group of Definitions

You can also provide a map of definitions. If at least one is fresh on the client, the renderer will delegate. It will still prefetch any stale definitions in the background on the server to ensure the client has all necessary data.

<NexusRenderer definitions={{ products: productDefinition.list, stats: statsDefinition.summary }} serverComponent={ServerGroup} clientComponent={ClientGroup} componentProps={{ title: 'Overview' }} />

Important Considerations

  • Hydration must be enabled: NexusRenderer requires NexusHydrationBoundary to be active in the component tree.
  • Client Component Exports: The clientComponent must be exported from a file that has the 'use client' directive at the top.
  • No Server-Only APIs: Do not use server-only APIs (like database clients or file system access) directly within a component passed to NexusRenderer, as it may need to render on the client. Fetch data outside the component and pass it as props.

See also

Last updated on