Copy & Language

Control the tone, language, and text content of your generated empty states.

Tone Options

The CLI generates copy in one of four tones. Each tone adjusts the heading, body text, and CTA labels to match the personality of your application.

Friendly

Warm, approachable language that feels conversational. The default tone.

Inbox

Heading: "Your inbox is empty"

Body: "When you receive messages, they'll show up here."

CTA: "Send a message"

Search

Heading: "No results found"

Body: "Try adjusting your search or browse our categories."

CTA: "Clear search"

Cart

Heading: "Your cart is empty"

Body: "Looks like you haven't added anything yet."

CTA: "Browse products"

Professional

Clear, direct language suited for enterprise and B2B products.

Inbox

Heading: "No messages"

Body: "Incoming messages will be displayed in this section."

CTA: "Compose message"

Search

Heading: "No matching results"

Body: "Refine your query or adjust the applied filters."

CTA: "Reset filters"

Cart

Heading: "Cart is empty"

Body: "Items added to your cart will appear here."

CTA: "View catalog"

Playful

Fun, lighthearted copy with personality. Great for consumer and social apps.

Inbox

Heading: "Nothing here yet!"

Body: "Your inbox is feeling lonely. Start a conversation!"

CTA: "Say hello"

Search

Heading: "Hmm, nothing matched"

Body: "We looked everywhere but came up empty. Try different words?"

CTA: "Try again"

Cart

Heading: "Your cart is hungry!"

Body: "Feed it some awesome items from our collection."

CTA: "Go shopping"

Minimal

Bare essentials. Short headings, no body text, terse CTAs. For interfaces where less is more.

Inbox

Heading: "No messages"

CTA: "Compose"

Search

Heading: "No results"

CTA: "Clear"

Cart

Heading: "Empty"

CTA: "Browse"

Setting a Global Tone

Set the default tone for all generated empty states in your config file. The CLI will use this tone when generating copy during npx hollows-ui build.

hollows.config.ts
ts
import { defineConfig } from 'hollows-ui'export default defineConfig({  copy: {    tone: 'professional', // 'friendly' | 'professional' | 'playful' | 'minimal'  },})

Per-Component Overrides

Override the generated copy for any individual component. You can customize the heading, body, and CTA text directly in the registry or via props.

Via the registry

src/hollows/registry.json
json
{  "user-inbox": {    "heading": "All caught up!",    "body": "You've read every message. Take a break.",    "cta": {      "label": "Refresh",      "action": "callback:onRefresh"    }  }}

Via component props

components/inbox.tsx
tsx
<Hollow  name="user-inbox"  empty={data?.length === 0}  heading="All caught up!"  body="You've read every message. Take a break."  ctaLabel="Refresh"  onCtaClick={handleRefresh}>  {data && <InboxList items={data} />}</Hollow>

Props always take precedence over registry values, so you can use the registry as a baseline and override specific fields at the component level.

Custom Copy Templates

Define reusable copy templates for component categories. When the CLI classifies a component, it will use your template instead of the built-in one.

hollows.config.ts
ts
import { defineConfig } from 'hollows-ui'export default defineConfig({  copy: {    tone: 'friendly',    templates: {      inbox: {        heading: 'Nothing in your {{name}} yet',        body: 'New {{itemType}} will appear here as they arrive.',        cta: 'Create {{itemType}}',      },      table: {        heading: 'No {{name}} found',        body: 'Try changing your filters or create a new entry.',        cta: 'Add {{itemType}}',      },      search: {        heading: 'No results for "{{query}}"',        body: 'Check your spelling or try broader terms.',        cta: 'Clear search',      },    },  },})

Template variables like {{name}} and {{itemType}} are resolved at build time using the component's classification metadata.

Internationalization

Hollows supports generating copy in multiple languages. Provide locale-specific overrides and the runtime adapter will pick the right one based on the active locale.

hollows.config.ts
ts
import { defineConfig } from 'hollows-ui'export default defineConfig({  copy: {    tone: 'friendly',    defaultLocale: 'en',    locales: {      en: {}, // uses defaults      es: {        templates: {          inbox: {            heading: 'Tu bandeja está vacía',            body: 'Los nuevos mensajes aparecerán aquí.',            cta: 'Redactar mensaje',          },        },      },      ja: {        templates: {          inbox: {            heading: 'メッセージはありません',            body: '新しいメッセージはここに表示されます。',            cta: 'メッセージを作成',          },        },      },    },  },})
app/providers.tsx
tsx
import { HollowsProvider } from 'hollows-ui/react'export function Providers({ children, locale }) {  return (    <HollowsProvider locale={locale}>      {children}    </HollowsProvider>  )}