Reference
Assets, rich text, links, error handling, and the full module and runtime reference for the Nuxt module for Localess.
Assets
There's no standalone asset-resolving helper. Use the client's assetLink() method, which builds a fully qualified URL from the configured origin and spaceId — never construct asset URLs by hand:
<script setup lang="ts">
import { type LocalessSchemaProps } from '@localess/vue';
import type { HeroSection } from '#shared/models/localess';
const props = defineProps<LocalessSchemaProps<HeroSection>>();
const client = useLocaless();
</script>
<template>
<img :src="client.assetLink(props.data.image)" :alt="props.data.imageAlt" />
<!-- With transform parameters -->
<img :src="client.assetLink(props.data.image, { w: 800, h: 600, q: 70, f: 'webp' })" alt="" />
</template>In a server route, call the same method on useLocalessServerClient().
| Param | Type | Description |
|---|---|---|
w | number | Target width in pixels |
h | number | Target height in pixels (combined with w, crops to cover the box) |
q | number | Output quality 1–100 (default 85; ignored for PNG) |
f | 'webp' | 'jpeg' | 'png' | 'avif' | Converts the output format |
download | boolean | Forces a browser download via Content-Disposition |
thumbnail | boolean | Extracts the first frame of an animated/video asset before resizing |
See Image Transforms for the full parameter reference.
Rich Text
<LocalessRichText> is auto-imported and renders a rich text field to native Vue VNodes — no Tiptap dependency at runtime, and no v-html:
<template>
<LocalessRichText :content="props.data.body" />
</template>| Prop | Type | Description |
|---|---|---|
content | LocalessRichTextInput | The 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 |
renderers | LocalessVueRichTextRenderers | Optional per-node/per-mark component overrides, keyed by element name |
The composable forms are auto-imported too: useLocalessRichText(doc, options?) returns a reactive ComputedRef<VNodeChild>, and useLocalessRichTextHtml(doc, options?) returns a ComputedRef<string> for a v-html binding. One-shot, non-reactive equivalents are renderRichText and renderRichTextToHtml.
Supported elements
| Kind | Elements |
|---|---|
| Nodes | doc, paragraph, heading (levels 1–6), bulletList, orderedList, listItem, codeBlock, text |
| Marks | bold, 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
Overrides are Vue components receiving the node's children as their default slot:
<LocalessRichText :content="props.data.body" :renderers="{ link: AppLink }" />Declare the props your override consumes, or set inheritAttrs: false, so unconsumed node attributes don't fall through onto the rendered element.
Rendering is shared across every Localess SDK by
@localess/richtext, so one document renders identically in Nuxt, React, Angular, Svelte, and Astro.
Links
findLink isn't re-exported — import it from @localess/client. It's a pure function with no client instance behind it, so it's safe anywhere:
<script setup lang="ts">
import { findLink } from '@localess/client';
import { type LocalessSchemaProps } from '@localess/vue';
import type { NavLink } from '#shared/models/localess';
const props = defineProps<LocalessSchemaProps<NavLink>>();
</script>
<template>
<NuxtLink :to="findLink(props.links, props.data.link)">{{ props.data.label }}</NuxtLink>
</template>ContentLink.type | Result |
|---|---|
"content" | Looks up link.uri in the links map and returns /<fullSlug> |
"url" | Returns link.uri as-is |
Error handling
getContentBySlug/getContentById throw LocalessApiError on a non-2xx response. Check error.status to turn a missing slug into Nuxt's own 404:
// server/api/content.ts
import { LocalessApiError } from '@localess/vue';
import { useLocalessServerClient } from '#localess/server';
export default defineEventHandler(async event => {
const client = useLocalessServerClient();
const slug = (getQuery(event).slug as string) || 'home';
try {
return await client.getContentBySlug(slug);
} catch (error) {
if (error instanceof LocalessApiError && error.status === 404) {
throw createError({ statusCode: 404, statusMessage: `Content not found for slug "${slug}".` });
}
throw error;
}
});Re-raise it on the page so Nuxt renders its error page rather than an empty layout:
const { data: content, error } = await useAsyncData('content', () => $fetch('/api/content'));
if (error.value) {
throw createError({ statusCode: error.value.statusCode ?? 500, statusMessage: error.value.statusMessage, fatal: true });
}Module setup errors
The module validates its config at build time and fails fast rather than at the first request:
| Condition | Result |
|---|---|
origin or spaceId missing | Throws — the build stops |
Neither token nor serverToken set | Throws — the build stops |
token missing, serverToken set | Warns. Valid server-only setup; useLocaless() will throw in the browser |
useLocalessServerClient() called in the browser | Throws at call time, naming the cause |
useLocalessServerClient() with no serverToken | Throws at call time, naming the option to set |
Module Reference
Options (nuxt.config.ts → localess)
| Option | Type | Default | Runtime |
|---|---|---|---|
origin | string | — (required) | public |
spaceId | string | — (required) | public |
token | string | — | public — reaches the browser |
serverToken | string | — | private — server only |
componentsDir | string | '~/components/localess' | build time |
componentNaming | 'exact' | 'camelCase' | 'PascalCase' | 'kebab-case' | 'snake_case' | 'lowercase' | 'exact' | build time |
components | Record<string, string> | {} | build time |
enableSync | boolean | false | public |
debug | boolean | false | public |
devtools | boolean | true | dev only |
cacheTTL | number | false | 300 | private — server client only |
componentNaming, componentsDir, and components are resolved when the registry is generated at build time — they add nothing to the runtime config.
Runtime config shape
| Key | Contains | Exposed to the browser |
|---|---|---|
runtimeConfig.public.localess | origin, spaceId, token, enableSync, debug | Yes |
runtimeConfig.localess | serverToken, cacheTTL | No |
Both are overridable at runtime with Nuxt's standard NUXT_* environment variables.
@localess/nuxt/server
| Export | Kind | Description |
|---|---|---|
useLocalessServerClient() | Function | A LocalessClient authenticated with the secret serverToken, memoised per server process. Server-only |
Import it through the #localess/server alias the module registers, which resolves in both the app and Nitro build graphs.
Auto-imported from @localess/vue
| Kind | Names |
|---|---|
| Components | LocalessDocument, LocalessComponent, LocalessRichText |
| Composables | useLocaless, useLocalessSync, useLocalessRichText, useLocalessRichTextHtml |
| Helpers | localessEditable, localessEditableField, renderRichText, renderRichTextToHtml |
Everything else — LocalessApiError, localessClient, and the LocalessSchemaProps / Content / ContentData types — is imported from @localess/vue explicitly — see packages/vue for its complete export list.
Module types
| Export | Description |
|---|---|
ModuleOptions | The full localess config block type |
PublicModuleOptions | The subset written to runtimeConfig.public.localess |
PrivateModuleOptions | The subset written to runtimeConfig.localess |