ianstormtaylor/slate · error · Error
The `useSlate` hook must be used inside the <Slate> componen
Error message
The `useSlate` hook must be used inside the <Slate> component's context.
What it means
This error is thrown by Slate.js's useSlate hook when it is called outside of a <Slate> provider component. useSlate relies on React's useContext(SlateSelectorContext) to access the editor instance and subscribe to its changes; when the context is absent (no <Slate> ancestor), addEventListener is undefined and the hook throws immediately to fail fast rather than silently returning a broken editor.
Source
Thrown at packages/slate-react/src/hooks/use-slate.tsx:16
import { MutableRefObject, useContext, useMemo, useReducer } from 'react'
import { Editor } from 'slate'
import { SlateSelectorContext } from './use-slate-selector'
import { useSlateStatic } from './use-slate-static'
import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect'
/**
* Get the current editor object and re-render whenever it changes.
*/
export const useSlate = (): Editor => {
const { addEventListener } = useContext(SlateSelectorContext)
const [, forceRender] = useReducer(s => s + 1, 0)
if (!addEventListener) {
throw new Error(
`The \`useSlate\` hook must be used inside the <Slate> component's context.`
)
}
useIsomorphicLayoutEffect(
() => addEventListener(forceRender),
[addEventListener]
)
return useSlateStatic()
}
const EDITOR_TO_V = new WeakMap<Editor, MutableRefObject<number>>()
const getEditorVersionRef = (editor: Editor): MutableRefObject<number> => {
let v = EDITOR_TO_V.get(editor)
if (v) {View on GitHub (pinned to 72a37c701e)
Solutions
- Move the offending component inside the <Slate editor={editor}> tree so the context is available.
- If the component cannot live inside <Slate>, pass the editor as a prop (or use the withReact editor instance you created) instead of useSlate().
- For external toolbars/portals, use useSlate() in a child of <Slate> and pass values down, or restructure so the portal's content is rendered from within the Slate subtree.
- In tests, wrap the component with <Slate editor={editor} initialValue={...}> (and the editor created with withReact(createEditor())).
- Ensure only one copy of slate-react and React is installed (dedupe node_modules) so the imported SlateSelectorContext matches the provider's.
Example fix
// before
function Toolbar() {
const editor = useSlate() // throws: outside <Slate>
return <button onClick={() => toggleMark(editor, 'bold')}>B</button>
}
export function App() {
return <>
<Slate editor={editor} initialValue={initialValue}>
<Editable />
</Slate>
<Toolbar />
</>
}
// after
export function App() {
return (
<Slate editor={editor} initialValue={initialValue}>
<Editable />
<Toolbar />
</Slate>
)
} Defensive patterns
Strategy: validation
Validate before calling
// Check context presence before calling useSlate (test/dev guard)
import { SlateContext } from 'slate-react'
// In a parent: const ctx = useContext(SlateContext)
// if (!ctx) render the component with editor passed as prop instead Type guard
// Runtime guard for wrapping components that optionally support Slate context
function useOptionalSlate(): Editor | null {
const ctx = React.useContext(SlateContext)
return ctx ?? null
} Prevention
- Always render editing-related components (toolbars, menus, balloons) as children of <Slate>.
- Pass the editor instance as a prop to components that must live outside the Slate tree.
- In tests, always mount with a <Slate editor={withReact(createEditor())} initialValue={...}> wrapper.
- Run npm ls slate-react react to verify a single copy of each before debugging context issues.
When it happens
Trigger: Calling useSlate() (directly or indirectly via useSlateWithV, useFocused, or a custom hook/component) in a component that is not rendered as a descendant of <Slate editor={editor}>. Also triggered by rendering toolbars, overlays, or portals outside the <Slate> tree, or by accessing the context in a module-level or class component where the hook runs outside the provider.
Common situations: Common with toolbars/menus rendered via React portals outside <Slate>, in unit tests (Enzyme/Jest) that shallow-render an editing component without the <Slate> wrapper, after refactoring when a component is moved out of the provider subtree, or when multiple React copies / slate-react versions cause the context instance used by the hook to differ from the one provided.
Related errors
- The `useEditor` hook must be used inside the <Slate> compone
- The `useSlateSelector` hook must be used inside the <Slate>
- The `useSlateStatic` hook must be used inside the <Slate> co
- [Slate] initialValue is invalid! Expected a list of elements
- [Slate] editor is invalid! You passed: ${Scrubber.stringify(
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/25b79ebc44d5d119.
Report an issue: GitHub.