React Client Integration

The @copypatch/react package provides the React context provider, editable text components, and hooks. It automatically connects to the same-origin /__copypatch/api/v2 route by default.

CopyPatchProvider

Wrap your component tree (or root page layout) with CopyPatchProvider. The provider manages the active locale, published text cache, draft revisions, and lazy editor loading:

HomePage.tsx
import { CopyPatchProvider, EditableText, useCopyPatch } from '@copypatch/react';

export function HomePage() {
  // Read editable copy for attributes, placeholders, or button labels
  const buttonLabel = useCopyPatch('home.cta.button', 'Get Started Free');
  const searchPlaceholder = useCopyPatch('home.search.placeholder', 'Search documentation...');

  return (
    <CopyPatchProvider locale="en">
      <header className="hero">
        <EditableText contentKey="home.hero.title" as="h1" className="hero-title">
          Let clients edit the copy. Not the website.
        </EditableText>
        <EditableText contentKey="home.hero.subtitle" as="p" className="hero-desc">
          Safe, same-origin inline copy editing for React applications.
        </EditableText>
        <div className="hero-actions">
          <input type="text" placeholder={searchPlaceholder} />
          <button type="button">{buttonLabel}</button>
        </div>
      </header>
    </CopyPatchProvider>
  );
}

Provider Configuration Props

Prop Type Default Description
locale string Required The active language identifier (e.g. "en", "tr", "de").
initialSnapshot ContentSnapshot undefined Pre-rendered content snapshot from the server (eliminates client layout shifts on load).
apiBase string "/__copypatch/api/v2" The base API path. Leave unset for standard same-origin hosting.

Components & Hooks API Reference

<EditableText>

Renders an inline editable text element. When normal visitors browse the site, it renders standard React elements with zero editing overhead. When an editor activates edit mode, it enables inline editing on click:

Prop Type Default Description
contentKey string Required Unique dot-separated identifier (e.g. "pricing.pro.title").
as string | ComponentType "span" HTML tag or React component to render (e.g. "h1", "h2", "p").
children string "" Fallback text rendered if no published snapshot is found in storage.
className string undefined CSS class names passed to the rendered DOM element.

useCopyPatch(contentKey, fallback)

A React hook to read editable string values for attributes where HTML elements cannot be directly rendered (e.g. placeholder, aria-label, title, alt, or option values).

useEditableText(contentKey, fallback)

A lower-level hook to build custom interactive components that integrate with CopyPatch's selection and mutation pipeline:

CustomBadge.tsx
import { useEditableText } from '@copypatch/react';

export function CustomBadge({ contentKey, defaultLabel }: { contentKey: string; defaultLabel: string }) {
  const { value, isEditing, editProps } = useEditableText(contentKey, defaultLabel);

  return (
    <span className="badge" {...editProps}>
      {value}
    </span>
  );
}

Strict Plain-Text Invariant

Zero XSS Design: CopyPatch stores and renders only plain text strings. HTML tags, <script> payloads, or markdown markup entered into editable fields are treated strictly as literal text, completely eliminating stored Cross-Site Scripting (XSS) risks.