sanity-i18n-translate

Guides correct usage of the Sanity Translate i18n component with stable components maps and componentProps.

6.3k|550|Updated Jan 18, 2017
One-click install
npx skills add https://github.com/sanity-io/sanity --skill sanity-i18n-translate
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: sanity-i18n-translate
Source: https://github.com/sanity-io/sanity/tree/main/.agents/skills/sanity-i18n-translate
Command: npx skills add https://github.com/sanity-io/sanity --skill sanity-i18n-translate

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Locale strings that contain markup (like '<Red>{{keyword}}</Red>') need the <Translate> component, but defining the components map inline during render creates new component identities every render, causing React to unmount and remount subtrees and lose state, DOM, and focus.

Core Features & Use Cases

  • Stable components map patterns: Shows how to map locale tags to intrinsic HTML strings, hoisted module-scope components, or components receiving data via componentProps.
  • Lint rule alignment: Explains the @repo/i18n/no-inline-translate-components oxlint rule and why useMemo or factory calls do not fix the identity problem.
  • Gotcha coverage: Documents TypeScript generic widening in componentProps, children behavior for wrapping vs self-closing tags, and RECOGNIZED_HTML_TAGS fallback behavior.
  • Use Case: When adding a search UI message like 'Search for "<Emphasis>{{keyword}}</Emphasis>"', use this Skill to write a compliant <Translate> usage that passes review and lint.

Quick Start

Ask the assistant to review or write a <Translate> usage for a locale string containing markup, following the hoisted-components and componentProps patterns.

Frequently Asked Questions about sanity-i18n-translate

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I use the Sanity Translate component with markup in locale strings?▼

Pass a components map that maps tag names in the locale string to React components or intrinsic HTML tag names, for example components={{Emphasis: 'em'}}. Use the plain t() function instead when the message contains no markup.

Why does the no-inline-translate-components lint rule fire on my Translate usage?▼

The rule fires because the components map is defined inline in the JSX attribute, creating a new component identity every render. React then unmounts and remounts the subtree, losing state and focus; hoist the components to module scope to fix it.

Does useMemo fix the inline components problem in Translate?▼

No, useMemo does not fix the component identity problem because dependency changes still recreate the components. Hoist the components to module scope and pass render-time data through the componentProps prop instead.

How do I pass data to components in the Translate components map?▼

Use the componentProps prop, which is forwarded to every non-string component in the map. Use 'as const' on literal values to prevent TypeScript from widening the generic, and declare children as optional in the component props.

When should I use t() instead of the Translate component?▼

Use the plain t() function whenever the locale message contains no markup or embedded components. <Translate> is more expensive to render, so it should be reserved for strings with tags that need mapping to components.