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

StrategyBehaviorUse 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 getOrphanBlockStats query returns counts of unreferenced blocks grouped by block type.
  • Orphan list — the listOrphanedBlocks query 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 deleteOrphanedBlocks mutation removes specified orphaned blocks. It verifies each block's usedIn is empty before deleting to prevent race conditions.
Previous
Component Architecture