Blocks
Deletion Lifecycle
When a document containing block references is deleted, Vextro decides what happens to the referenced blocks based on the configured deletion strategy.
Deletion strategies
| Strategy | Behavior | Use case |
|---|---|---|
"preserve" (default) | Blocks remain after document deletion. Their usedIn entry is removed. | Shared blocks, content reuse |
"delete-exclusive" | Blocks used only by the deleted document are also deleted. Shared blocks are preserved. | Single-use blocks, cleanup |
Configuring the strategy
Set the deletion strategy in your schema configuration:
import { createVextroSchema } from "vextro";
import { hero, cta } from "./blocks";
import { pages, posts } from "./collections";
const vextro = createVextroSchema({
collections: [pages, posts],
globals: [],
blocks: {
definitions: [hero, cta],
onDocumentDelete: "delete-exclusive",
},
}); Then pass it to the admin module:
import { createVextroAdminModule } from "vextro/convex/admin";
const admin = createVextroAdminModule({
query,
mutation,
components,
collectionDefinitions: vextro.collectionDefinitions,
blockDeletionStrategy: vextro.blockDeletionStrategy,
}); Shared blocks are always preserved
The delete-exclusive strategy checks each block's usedIn array at deletion time. If the block is referenced by any other document, it is preserved regardless of the configured strategy. Only blocks exclusively owned by the deleted document are removed.
Exclusive-block confirmation on delete
When a document references blocks, deleting it shows a confirmation dialog listing:
- Exclusive blocks that will be permanently deleted (only used by this document)
- Shared blocks that will be preserved (used by other documents)
This gives editors a chance to cancel the operation or reassign exclusive blocks to another document before deletion proceeds.
Orphan management
Orphaned blocks — blocks whose usedIn array is empty — can accumulate over time, especially with the "preserve" strategy. Vextro provides tools to monitor and clean up orphans:
- Orphan stats — the
getOrphanBlockStatsquery returns counts of unreferenced blocks grouped by block type. - Orphan list — the
listOrphanedBlocksquery returns individual orphaned blocks with their metadata. - Admin UI — the orphan blocks management page (at
/admin/orphan-blocks) shows all orphaned blocks with per-type counts and bulk cleanup actions. - Bulk cleanup — the
deleteOrphanedBlocksmutation removes specified orphaned blocks. It verifies each block'susedInis empty before deleting to prevent race conditions.