Localess
TanStack Start

Content

Fetch content and render it dynamically by schema in a TanStack Start app, across server and client rendering.

Fetching content

getLocalessClient()

Returns the LocalessClient instance created during localessInit. Use this in server-side data-fetching functions.

import { getLocalessClient } from "@localess/react";

async function fetchPageData(locale?: string) {
  const client = getLocalessClient();
  return client.getContentBySlug<Page>('home', { locale });
}

Throws an error if called before localessInit has been executed.

useLocaless Hook

useLocaless<T> fetches content by slug in a Client Component and automatically subscribes to Visual Editor live updates when enableSync is active.

'use client';

import { useLocaless, LocalessComponent } from "@localess/react";
import type { Page } from "./.localess/localess";

export function PageView({ slug }: { slug: string }) {
  const content = useLocaless<Page>(slug, { locale: 'en' });

  if (!content) return <div>Loading…</div>;

  return (
    <main>
      {content.data.body.map(item => (
        <LocalessComponent key={item._id} data={item} links={content.links} />
      ))}
    </main>
  );
}

Parameters

ParameterTypeRequiredDescription
slugstring | string[]YesContent slug. Arrays are joined with / — e.g. ['blog', 'post']'blog/post'
optionsContentFetchParamsNoSame fetch options as getContentBySlug (locale, version, resolveReference, resolveLink)

Returns Content<T> | undefinedundefined while the initial fetch is in progress. Content<T> includes data, links, references, and assets (a map of resolved content assets keyed by asset ID).

When enableSync is active and the page is rendered inside the Localess Visual Editor iframe, the hook automatically subscribes to input / change events and updates the returned content in place.

Rendering content

LocalessComponent

LocalessComponent is a dynamic renderer that maps Localess content data to your registered React components by schema key. It automatically applies Visual Editor attributes when sync is enabled.

import { LocalessComponent } from "@localess/react";

// Render a single content block
<LocalessComponent data={content.data} />

// Render a list of nested blocks
{data.body.map(item => (
  <LocalessComponent
    key={item._id}
    data={item}
    links={content.links}
    references={content.references}
  />
))}

Props

PropTypeRequiredDescription
dataContentDataYesContent data object from Localess. The component looks up data._schema in the component registry
linksLinksNoResolved content links map, forwarded to the rendered component
referencesReferencesNoResolved references map, forwarded to the rendered component
assetsAssetsNoResolved content assets map (keyed by asset ID), forwarded to the rendered component
refReact.Ref<HTMLElement>NoRef forwarded to the rendered component's root element
...restanyNoAny additional props are forwarded to the rendered component

If a schema key is not registered and no fallbackComponent is configured, LocalessComponent renders an error message in the DOM.

Component Registry API

The registry is configured once, through localessInit()'s components and fallbackComponent options. There is no mutation API for adding, replacing, or removing entries afterwards.

Read-only accessors are available for inspecting what was registered:

import { getComponent, getFallbackComponent, isSyncEnabled } from "@localess/react";

// Retrieve a component by schema key, or undefined if unregistered
const Component = getComponent('hero');

// The configured fallback, if any
const fallback = getFallbackComponent();

// Whether Visual Editor sync is active (enabled, in a browser, and framed)
const syncEnabled = isSyncEnabled();

To vary the registry by route or environment, branch when you build the map you pass to localessInit(), rather than mutating it afterwards.

On this page