Localess
React Router

Reference

Assets, rich text, links, error handling, and the export reference for Localess in React Router.

Assets

resolveAsset(asset, params?)

Resolves a ContentAsset object to a fully qualified URL using the initialized client's origin. Pass an AssetTransformParams object as the second argument to request a resized image or a different output format — the params are appended as query string parameters that the Localess asset endpoint uses to transform the image on the fly. See Image Transforms for the full parameter reference.

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

const Image = ({ data }) => (
  <img src={resolveAsset(data.image)} alt={data.imageAlt} />
);
import { resolveAsset } from "@localess/react";

function HeroImage({ image }: { image: ContentAsset }) {
  return (
    <img
      // Smaller, WebP thumbnail for a card
      src={resolveAsset(image, { w: 400, f: 'webp' })}
      alt={image.alt ?? ''}
    />
  );
}

function ProductImage({ image }: { image: ContentAsset }) {
  return (
    <img
      // Fixed box crop + quality control
      src={resolveAsset(image, { w: 800, h: 600, q: 70, f: 'avif' })}
      alt={image.alt ?? ''}
    />
  );
}
ParamTypeDescription
wnumberTarget width in pixels
hnumberTarget height in pixels (combined with w, crops to cover the box)
qnumberOutput quality 1–100 (default 85; ignored for PNG)
f'webp' | 'jpeg' | 'png' | 'avif'Converts the output format
downloadbooleanForces a browser download via Content-Disposition
thumbnailbooleanExtracts the first frame of an animated/video asset before resizing

Rich Text

Rich text renders from the field's Tiptap JSON straight to React elements — no Tiptap dependency, no dangerouslySetInnerHTML, and no browser APIs, so the same call works in a SPA, during SSR, and inside a React Server Component.

<LocalessRichText />

The component form, and the one to reach for by default.

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

const Article = ({ data }) => (
  <article>
    <h1>{data.title}</h1>
    <LocalessRichText content={data.body} />
  </article>
);
PropTypeDescription
contentLocalessRichTextInputThe rich text field value. Accepts a full document, a single node, an array of nodes, or null/undefined, so a field value passes through without casting
renderersLocalessReactRichTextRenderersOptional per-node/per-mark component overrides, keyed by element name

renderRichText(content, options?)

The function form, for when you need the result as a value rather than as JSX — handing it to a layout component, wrapping it, or checking whether it produced anything.

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

const body = renderRichText(data.body);

Returns null for an empty or absent value, so an unfilled optional field renders nothing.

Supported elements

KindElements
Nodesdoc, paragraph, heading (levels 1–6), bulletList, orderedList, listItem, codeBlock, text
Marksbold, italic, strike, underline, code, link

An unknown node is skipped and an unknown mark renders its children unwrapped, each with a one-time console.warn outside production — so a document authored against a newer Localess release degrades instead of throwing.

Overriding a renderer

Pass renderers to replace the default output for one element. The key is the node or mark name, and the component receives that node's own fields plus children:

import { LocalessRichText } from "@localess/react";
import NextLink from "next/link";

const Link = ({ attrs, children }) => <NextLink href={attrs.href}>{children}</NextLink>;

<LocalessRichText content={data.body} renderers={{ link: Link }} />;

The same map handles a custom heading that adds anchor links, or a codeBlock that runs a syntax highlighter. Anything you don't override keeps its default rendering.

Rendering is shared across every Localess SDK by @localess/richtext, so one document renders identically in React, Angular, Vue, Svelte, and Astro.

Resolves a ContentLink field to a URL string. Use it to build href values from Localess content links.

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

// type: 'content' → '/' + fullSlug, or '/not-found' if not in map
// type: 'url'     → raw URI unchanged
const href = findLink(content.links, data.ctaLink);

const NavLink = ({ data, links }) => (
  <a href={findLink(links, data.link)}>{data.label}</a>
);

Error handling

getContentBySlug/getContentById throw LocalessApiError on a non-2xx API response — check error.status to distinguish a missing slug (404) from other failures:

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

async function fetchPageData(slug: string) {
  try {
    return await getLocalessClient().getContentBySlug(slug);
  } catch (error) {
    if (error instanceof LocalessApiError && error.status === 404) {
      return undefined;
    }
    throw error;
  }
}

Export Reference

The table below shows which symbols are available in each export.

Symbol@localess/react@localess/react/ssr@localess/react/vite
localessInitYesYesNo — use the localess() plugin instead
localess (Vite plugin)NoNoYes
getLocalessClientYesYesNo — import from @localess/react
getComponent / getFallbackComponentYesYesNo
resolveAssetYesYesNo — import from @localess/react
LocalessComponentYesNoNo — import from @localess/react
LocalessServerComponent / LocalessServerDocumentNoYesNo
LocalessRichText / renderRichTextYesYesNo — import from @localess/react
findLinkYesYesNo — import from @localess/react
isServerYesYesNo
All content typesYesYesNo
LocalessDocumentYesNoNo — import from @localess/react
useLocalessYesNoNo — import from @localess/react
localessEditable / localessEditableFieldYesYesNo — import from @localess/react
isBrowser / isIframeYesYesNo
isSyncEnabled / localessSyncOn / localessSyncOnChange / localessSyncReadyYesNoNo
Sync event types (LocalessSync, EventToApp, EventToAppOf, …)YesYesNo

@localess/react/vite is narrowly scoped to the Vite plugin itself (localess() and its option types) — it doesn't re-export the runtime API. Import getLocalessClient, LocalessComponent, and everything else from the default @localess/react export, as shown in Setup above.

@localess/react/vite/virtual-modules is a separate, type-only subpath — ambient declarations for the virtual:localess-init/virtual:localess-components modules the plugin generates, needed only in tsconfig.json's types array (see Setup), never imported directly.

On this page