---
title: "useBlokReady Hook — Scoped Editor Readiness in React"
description: "Wait for the Blok editors inside one container to finish rendering, with useBlokReady — scoped, reactive, and safe for empty lists."
source: https://blokeditor.com/docs/use-blok-ready/
lastmod: 2026-09-07
---

Framework JavaScript

Framework adapters useBlokReady

On this page useBlokReady(options?)

# useBlokReady(): scoped editor readiness

Live readiness of the Blok editors inside a DOM subtree, as a boolean you can render from — the useBlokReady(options) hook in @bloklabs/react, the useBlokReady(options) composable in @bloklabs/vue (returns a ref), and injectBlokReady(options) in @bloklabs/angular (returns a signal). All three wrap the same core registry behind Blok.readyState() and Blok.subscribeReady(), so they cannot drift. It answers the question a comments list or a form actually has: are MY editors ready? Scope it with the ref you already hold on the container, so an unrelated editor elsewhere on the page cannot hold your gate closed. It is a live signal, not a one-shot latch: an editor mounted later re-closes the gate, and with settleOn: 'rendered' so does every re-render from a changed data prop. A scope holding no editors is ready, so the empty-list case needs no special-casing. It starts false and takes its first real reading once the scope element is attached (React: the mount effect; Vue: onMounted; Angular: afterNextRender), and a scope you asked for that has not resolved yet reports false rather than silently falling back to the whole page — over-waiting is safe, under-waiting is a bug.

Last updated Jul 22, 2026 [Edit this page on GitHub](https://github.com/JackUait/blok/blob/main/docs/src/components/api/api-data.ts)

### Reaching the editor instance

The methods below run on the editor you created with new Blok(). They are available once editor.isReady resolves.

TypeScript

```
// You already hold the instance returned by the constructor.
const editor = new Blok({ holder: 'editor' });
await editor.isReady;

// Call any API method on it.
editor.caret.setToLastBlock('end');
```

## Methods

### useBlokReady(options?)

boolean

True when every Blok editor in scope is settled. Re-evaluates on every readiness change (construction, boot, render-state flip, destroy) and unsubscribes on unmount.

Parameters

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `options.within` | `RefObject<Element | null> | Element | null` | — | — | Restrict the wait to editors mounted inside this element. A ref is re-read on every readiness change, so one that attaches after the first render is picked up. Omit it to observe every editor on the page. |
| `options.settleOn` | `'ready' | 'rendered'` | — | `'ready'` | 'ready' settles when each editor has finished booting. 'rendered' also waits for its content to be in the DOM, which re-arms on every post-boot re-render. |

TypeScript

```
const ready = useBlokReady({ within: listRef, settleOn: 'rendered' });
```

TypeScript

```
import { useRef } from 'react';
import { BlokEditor, useBlokReady } from '@bloklabs/react';

export function Comments({ comments }) {
  const listRef = useRef<HTMLDivElement>(null);

  // True once every editor inside listRef has its content in the DOM.
  // Re-arms whenever a comment's data changes and it re-renders.
  const ready = useBlokReady({ within: listRef, settleOn: 'rendered' });

  return (
    <>
      <div ref={listRef}>
        {comments.map((c) => (
          <BlokEditor key={c.id} data={c.body} readOnly />
        ))}
      </div>
      {!ready && <Skeleton />}
      <Composer autoFocus={ready} />
    </>
  );
}

// Vue — a ref:
// const list = ref<HTMLElement | null>(null);
// const ready = useBlokReady({ within: list, settleOn: 'rendered' });

// Angular — a signal, from an injection context:
// @ViewChild('list', { static: true }) listRef!: ElementRef<HTMLElement>;
// readonly ready = injectBlokReady({
//   within: () => this.listRef?.nativeElement ?? null,
//   settleOn: 'rendered',
// });
```
