Skip to content

Inline Editing

How inline text editing works in InlineCMS.

Inline editing is the core feature of InlineCMS. Any HTML element can become editable by adding the inline-cms attribute.

Add the attribute to any element and it gains an edit affordance — the rendered output is unchanged for visitors.

Editable heading tsx
<h1 inline-cms>Welcome to our site</h1>
<p inline-cms>We build great things.</p>
Result

Welcome to our site

We build great things.

The Vite plugin transforms these at build time into InlineCMS wrapper components with stable fingerprint keys. The inline-cms attribute never ships to visitors — it’s compiled away, leaving the exact markup you wrote:

What you write
<p inline-cms>
We build great things.
</p>
What readers see
<p>
We build great things.
</p>

To a visitor the page reads as plain HTML. To a logged-in editor the same element becomes a click-to-edit target — without the content shifting. Edit mode is purely additive: InlineCMS paints decoration around and behind the element, so the layout stays exactly where the visitor sees it (true WYSIWYG):

Reader view Editor mode

We build great things.

Editing is purely additive: InlineCMS paints a dashed outline, a soft tint and a label around and behind the bound element. The layout a visitor sees is never touched.
PropRequiredPurpose
inline-cmsYesOpts this element into CMS editing
inline-cms-keyNoStable key override (auto-generated by Vite plugin)
inline-cms-labelNoLabel shown in the edit UI
inline-cms-typeNoOverride the inferred field type
inline-cms-groupNoGroup related fields in the edit UI

InlineCMS infers the field type from the HTML tag:

Inferred type
HTML tags
Aa text
h1–h6 · p · span · label · a · li · figcaption · blockquote
richtext
div · section · article · aside · main
image
img
video
video

You can override the inferred type:

<div inline-cms inline-cms-type="text">Plain text only</div>
  1. Editor clicks Editor login in the toolbar
  2. After authentication, clicks Edit page
  3. Editable elements show a dashed outline on hover
  4. Click an element to start editing — it becomes contentEditable
  5. Type to edit. Changes are tracked locally.
  6. Click Save draft to persist without publishing
  7. Click Publish to make changes live

If you prefer named components over the prop API:

import { InlineH1, InlineP, InlineImg } from '@inlinecms/react'
function Hero() {
return (
<section>
<InlineH1 inline-cms-key="hero-title">Welcome</InlineH1>
<InlineP>We build great things.</InlineP>
<InlineImg src="/hero.jpg" />
</section>
)
}

Wrap existing components you don’t want to modify:

import { withCMS } from '@inlinecms/react'
import { HeroSection } from './HeroSection'
const CMSHero = withCMS(HeroSection, {
componentId: 'hero-section',
fields: [
{ key: 'title', selector: 'h1', type: 'text' },
{ key: 'subtitle', selector: 'p', type: 'text' },
{ key: 'image', selector: 'img', type: 'image' },
],
})
Was this page helpful? Your feedback goes straight to the docs team.