| Import | Exports | Use |
|---|---|---|
platejs | URL helpers, shared object types, PLUGINS, utility plugins | Framework-wide headless contracts and first-party identities. |
platejs/react | Ref/effect hooks, useSelectionFragmentProp, BlockPlaceholderPlugin | React-only framework and registry behavior. |
| Export | Contract |
|---|---|
isDefined(value) | Narrows null and undefined out of a value. |
isUrl(value) | Loosely validates URL strings with a recognized protocol and domain. |
sanitizeUrl(url, options) | Rejects disallowed schemes and returns a normalized URL, internal path, fragment, or null. |
IS_APPLE | Reports whether the current browser user agent is macOS. |
AnyObject | String-keyed object whose values are intentionally unchecked. |
UnknownObject | String-keyed object whose values require narrowing. |
Nullable<T> | Adds null to every property of T. |
import { isUrl, sanitizeUrl } from 'platejs';
export function getSafeLink(value: string) {
if (!isUrl(value)) return null;
return sanitizeUrl(value, {
allowedSchemes: ['http', 'https'],
});
}import { isUrl, sanitizeUrl } from 'platejs';
export function getSafeLink(value: string) {
if (!isUrl(value)) return null;
return sanitizeUrl(value, {
allowedSchemes: ['http', 'https'],
});
}PLUGINS is the first-party capability-name catalog used by copied registry
code. An element plugin separately exposes its persisted type; a property
plugin exposes its persisted key. Both default to the plugin name, but a
plugin author can declare a different value at creation.
| Export | Contains | Use |
|---|---|---|
PLUGINS | First-party capability names such as paragraph, codeBlock, bold, and fixedToolbar | Plugin lookup, dependencies, targets, and copied registry plugin references. Persisted identities come from editor.plugin(Plugin).schema.type, editor.plugin(Plugin).schema.key, generated schema handles, or explicit document literals. |
PluginName | Union of all values in PLUGINS | APIs that accept any first-party plugin identity. |
const value = [
{
type: 'paragraph',
children: [{ bold: true, text: 'Hello' }],
},
];const value = [
{
type: 'paragraph',
children: [{ bold: true, text: 'Hello' }],
},
];Behavior-only plugins such as PLUGINS.fixedToolbar still have a name but do
not create a document node or property.
import { PLUGINS, TrailingBlockPlugin } from 'platejs';
export const trailingBlock = TrailingBlockPlugin.configure({
initialState: {
type: 'paragraph',
},
});import { PLUGINS, TrailingBlockPlugin } from 'platejs';
export const trailingBlock = TrailingBlockPlugin.configure({
initialState: {
type: 'paragraph',
},
});Feature packages own their persisted types. Their readable aliases are derived
from the same plugin schema used at runtime, so platejs does not carry
a central AST map.
import type { ImageElement } from 'platejs/media';
export function getImageUrl(element: ImageElement) {
return element.url;
}import type { ImageElement } from 'platejs/media';
export function getImageUrl(element: ImageElement) {
return element.url;
}Use ElementOf<typeof Plugin> for one descriptor-owned element shape and
ValueOf<Editor> for the complete installed document vocabulary.
The Editor below is generated from the app's authored plugin module; it is
not installed by @plate/editor-plugins. Follow
Exact Generated Editor Types and
enforce plate generate --check <entry> in CI.
import type { ValueOf } from 'platejs';
import type { Editor } from '@/components/editor/plugins.generated';
type MyValue = ValueOf<Editor>;import type { ValueOf } from 'platejs';
import type { Editor } from '@/components/editor/plugins.generated';
type MyValue = ValueOf<Editor>;| Export | Name | Behavior |
|---|---|---|
ExitBreakPlugin | PLUGINS.exitBreak | Adds transaction commands around insertExitBreak. |
NormalizeTypesPlugin | PLUGINS.normalizeTypes | Normalizes configured root paths to a required type or strictType. |
SingleBlockPlugin | PLUGINS.singleBlock | Forces the editor value into one block and turns hard breaks into soft breaks. |
SingleLinePlugin | PLUGINS.singleLine | Forces one block and strips line-break characters from text nodes. |
TrailingBlockPlugin | PLUGINS.trailingBlock | Ensures a trailing block exists at the configured level and type. |
withTrailingBlock | Override editor helper | Implements the trailing block normalization logic used by TrailingBlockPlugin. |
Use the plugin guide pages for options and examples: Exit Break, Forced Layout, Single Block, and Trailing Block.
| Hook | Returns | Use |
|---|---|---|
useComposedRef(...refs) | React.RefCallback<T> | Assigns one node to callback refs and ref objects, including React 19 cleanup callbacks. |
useIsomorphicLayoutEffect | React effect hook | Uses useLayoutEffect in the browser and useEffect during SSR. |
useSelectionFragmentProp(options?) | unknown | Reads a property from the selected fragment. |
| Plugin | Name | Behavior |
|---|---|---|
BlockPlaceholderPlugin | PLUGINS.blockPlaceholder | Tracks the current empty block and injects placeholder and optional className props into matching block components. |
BlockPlaceholderPlugin defaults to paragraph placeholders and only targets a
focused, editable, collapsed selection. Configure placeholders by plugin name
and query by node/path.
import { PLUGINS } from "platejs";
import { BlockPlaceholderPlugin } from "platejs/react";
export const blockPlaceholderPlugin = BlockPlaceholderPlugin.configure({
initialState: {
placeholders: {
[PLUGINS.paragraph]: "Type something...",
},
query: ({ path }) => path.length === 1,
},
});import { PLUGINS } from "platejs";
import { BlockPlaceholderPlugin } from "platejs/react";
export const blockPlaceholderPlugin = BlockPlaceholderPlugin.configure({
initialState: {
placeholders: {
[PLUGINS.paragraph]: "Type something...",
},
query: ({ path }) => path.length === 1,
},
});