Rich text editor, custom toolbar shortcut to create specific block

Hi, is it possible to add a toolbar shortcut that would open specific block editor’s modal instead of pressing blocks shortcut and then choosing X block?

Hi @Marcis

It may be possible with a custom tiptapToolbarExtension but it’s not something I’ve tried. There’s nothing out of the box that bypasses the RTE blocks picker modal.

I did ask AI and they came back with the following but you may need check if this works or not…

import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<ManifestTypes> = [
  {
    type: 'tiptapToolbarExtension',
    kind: 'button',
    alias: 'My.Tiptap.Toolbar.InsertCallout',
    name: 'Insert Callout Block',
    api: () => import('./insert-callout.tiptap-toolbar-api.js'),
    forExtensions: ['Umb.Tiptap.Block'], // requires the core Block extension to be enabled
    meta: {
      alias: 'insertCalloutBlock',
      icon: 'icon-alert',
      label: 'Insert Callout',
    },
  },
];
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import type { Editor } from '@umbraco-cms/backoffice/tiptap'; // NB: NOT /external/tiptap in v17
import { UMB_BLOCK_RTE_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/block-rte';

// Replace with the GUID of the element type you want this button to insert
const CALLOUT_CONTENT_ELEMENT_TYPE_KEY = '00000000-0000-0000-0000-000000000000';

export default class InsertCalloutToolbarApi extends UmbTiptapToolbarElementApiBase {
  #manager?: typeof UMB_BLOCK_RTE_MANAGER_CONTEXT.TYPE;

  constructor(host: any) {
    super(host);
    this.consumeContext(UMB_BLOCK_RTE_MANAGER_CONTEXT, (ctx) => {
      this.#manager = ctx;
    });
  }

  override async execute(editor?: Editor) {
    if (!editor || !this.#manager) return;

    // Ask the block manager to create a new block of the desired type.
    // This opens the block's workspace modal directly — no picker step.
    const created = await this.#manager.create({
      contentElementTypeKey: CALLOUT_CONTENT_ELEMENT_TYPE_KEY,
    });

    if (!created?.content?.key) return;

    // Drop the reference into Tiptap at the cursor.
    editor
      .chain()
      .focus()
      .insertContent(
        `<umb-rte-block data-content-key="${created.content.key}"><!--Umbraco-Block--></umb-rte-block>`
      )
      .run();
  }
}

That may at least give you a starting point.

Justin