@platejs/slate-layout derives page geometry, line fragments, and page-level mount plans
from a Slate editor. Use it for pagination experiments, print-like surfaces,
and page virtualization that still keeps Slate as the document model.
The package is experimental. Keep production use behind explicit flags until your browser, export, table, image, and collaboration requirements are proven.
Page Layout
Create a layout reader with createSlateLayout. The reader chooses the built-in
measurement engine and derives layout from the current editor snapshot and your
page settings.
import { createSlateLayout } from "@platejs/slate-layout";
const layout = createSlateLayout(editor, () => ({
page: {
margins: 72,
preset: "letter",
},
}));import { createSlateLayout } from "@platejs/slate-layout";
const layout = createSlateLayout(editor, () => ({
page: {
margins: 72,
preset: "letter",
},
}));The layout output is derived state. Store document content in Slate roots and store product settings in state fields; do not write layout fragments into the document unless your product explicitly needs authoritative page breaks.
React Usage
Use PagedEditable from @platejs/slate-layout/react when the editor surface should
render pages.
import { Slate, useSlateEditor } from "@platejs/slate-react";
import { PagedEditable, useSlateLayout } from "@platejs/slate-layout/react";
const DocumentEditor = () => {
const editor = useSlateEditor({
initialValue,
});
const layout = useSlateLayout(editor, {
page: { margins: 72, preset: "letter" },
});
return (
<Slate editor={editor}>
<PagedEditable layout={layout} />
</Slate>
);
};import { Slate, useSlateEditor } from "@platejs/slate-react";
import { PagedEditable, useSlateLayout } from "@platejs/slate-layout/react";
const DocumentEditor = () => {
const editor = useSlateEditor({
initialValue,
});
const layout = useSlateLayout(editor, {
page: { margins: 72, preset: "letter" },
});
return (
<Slate editor={editor}>
<PagedEditable layout={layout} />
</Slate>
);
};PagedEditable wraps Editable, so normal Editable props still apply:
renderElement, renderLeaf, decorate, domStrategy, and keyboard handlers
stay on the editor surface.
Use createSlatePageLayout or useSlatePageLayout only when you provide an
explicit engine, such as a custom measurement engine or
pretextPageLayoutEngine().
Headless And Static Use
createSlateLayout can run outside React and can fall back to an estimated
engine when browser canvas measurement is unavailable. Use that for previews,
tests, and export planning. Treat static output as derived geometry, not as an
authoritative PDF, print, or collaboration layout source unless your product
provides the measurement engine and proof for that target.
Provider-Owned Boxes
Tables, images, embeds, and other block formatting context style nodes should own their layout units through provider code. The layout engine should not split the Slate table node just to paginate a table. It can paginate provider-owned row units while the document tree stays stable.
Page Virtualization
Use page-level virtualization when pagination is enabled. Virtualizing whole pages keeps layout, selection, and page chrome aligned better than mounting and unmounting individual blocks inside a page.
The page mount plan keeps pages mounted when they are visible, selected, promoted by interaction, or involved in composition. That makes it the right boundary for print-like editors.
Measurement Caveat
The built-in Pretext-backed engine measures text with browser font metrics. That gives stable results inside one browser profile, but different operating systems and browsers can still produce slightly different line breaks. Products that need exact collaboration or export parity should use an authoritative page break source or a shared measurement profile.