Localess
Next.js

Reference

Assets, rich text, links, error handling, and the export reference for Localess in Next.js.

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, alt }: { image: ContentAsset; alt: string }) {
  return (
    <img
      // Smaller, WebP thumbnail for a card
      src={resolveAsset(image, { w: 400, f: 'webp' })}
      alt={alt}
    />
  );
}

function ProductImage({ image, alt }: { image: ContentAsset; alt: string }) {
  return (
    <img
      // Fixed box crop + quality control
      src={resolveAsset(image, { w: 800, h: 600, q: 70, f: 'avif' })}
      alt={alt}
    />
  );
}
ParamTypeDescription
wnumberTarget width in pixels — whole number, 1–8192. Never upscales: a width above the source redirects to the source width
hnumberTarget height in pixels — same rules as w. Combined with w, the result is governed by fit
fit'cover' | 'contain' | 'inside' | 'outside' | 'fill'How the image fills the box when both w and h are set (default cover)
qnumberOutput quality, whole number 1–100. Defaults per format: JPEG and WebP 80, AVIF 50
f'webp' | 'jpeg' | 'png' | 'avif'Converts the output format. Without it, the stored format is kept
thumbnailbooleanExtracts the first frame of an animated/video asset before resizing

An out-of-range or fractional w, h or q throws a TypeError before the URL is built. For the untouched uploaded file, or to force a browser download, use the original and download links described below rather than a transform parameter.

A bare resolveAsset(asset) URL is a rendition, not the uploaded file: still images are re-encoded at their format's default quality even with no parameters. When you need the exact bytes that were uploaded, or want the browser to save the file instead of displaying it, use the dedicated helpers:

import { resolveAssetDownload, resolveAssetOriginal } from '@localess/react';

<a href={resolveAssetOriginal(data.heroImage)}>View the original file</a>
<a href={resolveAssetDownload(data.brochure)} download>Download</a>

Neither accepts transform parameters. A request that adds any is rejected with 400. Downloads keep non-ASCII file names intact.

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 { sanitizeUrl } from "@localess/richtext";
import NextLink from "next/link";

const Link = ({ attrs, children }) => <NextLink href={sanitizeUrl(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.

A custom renderer receives the raw attributes — the built-in URL sanitising only runs on default rendering. Pass any URL you render yourself through sanitizeUrl from @localess/richtext (a dependency of @localess/react), as above, so a javascript: link can't reach the page.

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/rsc
localessInitYesYesYes
getLocalessClientYesYesYes
localessClient (standalone client)NoYesYes
isSyncConfigured / getOriginYesNoNo
LocalessApiErrorYesYesYes
getComponent / getFallbackComponentYesYesYes
resolveAssetYesYesYes
resolveAssetOriginal / resolveAssetDownloadYesYesYes
LocalessComponentYesNoYes
LocalessServerComponent / LocalessServerDocumentNoYesYes
LocalessServerComponentPropsNoYesYes
LocalessRichText / renderRichTextYesYesYes
findLinkYesYesYes
isServerYesYesYes
All content typesYesYesYes
LocalessDocumentYesNoYes
useLocalessYesNoYes
localessEditable / localessEditableFieldYesYesYes
isBrowser / isIframeYesYesYes
isSyncEnabled / localessSyncOn / localessSyncOnChange / localessSyncReadyYesNoYes
Sync event types (LocalessSync, EventToApp, EventToAppOf, …)YesYesYes

On this page