SDK

React SDK

@obelism/content-react: ContentBridge, useLiveEntry for live preview, hooks for the bridge and prompt box, and a RichText component that works in server components.

2 min read
npm i @obelism/content @obelism/content-react

@obelism/content-react re-exports editable and the types of @obelism/content. Everything is a client component except RichText.

Live preview

app/layout.tsx
import { ContentBridge } from '@obelism/content-react'

export default function RootLayout({ children }) {
	return (
		<html lang="en">
			<body>
				{/* Starts the bridge, so blocks are selectable on every page. */}
				<ContentBridge />
				{children}
			</body>
		</html>
	)
}
components/Page.tsx
'use client'

import { editable, useLiveEntry } from '@obelism/content-react'

export const Page = ({ entry }) => {
	// The editor's unsaved version while editing; `entry` otherwise.
	const { fields } = useLiveEntry(entry)

	return (
		<main {...editable(entry)}>
			{fields.body.map((block) => (
				<section key={block._uid} {...editable(block)}>
					…
				</section>
			))}
		</main>
	)
}

Reference

  • <ContentBridge url? prompt? pagePath? />: starts the bridge. Pass url only when the CMS isn't content.obelism.studio; prompt={false} leaves the prompt box out; pagePath(path, locale) maps a CMS path in the page's locale to the site's URL for pages made with New page (default / + the path).
  • useLiveEntry(entry, { url? }): entry, or the editor's live version of it.
  • useContentBridge(): { isEditing, entryId, environment }, after hydration.
  • useContentBridgeEvent('saved' | 'published' | 'update', listener): e.g. router.refresh() on publish.
  • useContentPrompt(): { available, prompting, canUndo, selectedUid, prompt, createPage, undo, select }, for your own prompt UI with <ContentBridge prompt={false} />.

Rich text

import { RichText } from '@obelism/content-react'

export const Body = ({ entry }) => (
	<RichText
		document={entry.fields.body}
		embeddedEntry={({ entry }) => <Card entry={entry} />}
		nodes={{ heading: ({ node, children }) => <h2>{children}</h2> }}
		marks={{
			link: ({ mark, children }) => (
				<Link href={mark.attrs.href}>{children}</Link>
			),
		}}
	/>
)

It isn't a client component, so it works in server components too. Links are only rendered for safe URLs (http(s):, mailto:, tel:, # and paths). See rich text for the nodes and marks.

On this page

Marks in the margin

  • Note
  • Watch out
  • Updated

Scribes marked doubtful lines in the margin. That practice is called obelism.

Stuck on a step?