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:
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:
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.