Search the Qalma docs

Type at least two characters to get started.

Docs

Image

ImagePlugin adds an inline, selectable, draggable image node. It does not render an upload UI. Your Angular app owns URL inputs, file pickers, image validation copy, and previews.

import { ImagePlugin, createQalmaEditor } from '@qalma/editor';

const editor = createQalmaEditor({
  plugins: [ImagePlugin],
});

Commands and query

Contract Description
insertImage Inserts an inline image at the current selection and selects it.
updateImage Updates the selected image node.
removeImage Deletes the selected image node.
query<ImageState>('image') Returns the selected image state, or null when an image node is not selected.

insertImage accepts either a string URL or an object.

editor.execute('insertImage', {
  src: 'https://picsum.photos/seed/qalma-ink/720/360',
  alt: 'A calm, textured backdrop',
  title: 'Example image',
});

updateImage accepts a partial image value and merges it with the currently selected image before validating the result.

editor.execute('updateImage', {
  alt: 'Updated alt text',
  title: null,
});

Image state

import { ImageState } from '@qalma/editor';

const image = editor.query<ImageState>('image');

if (image) {
  console.log(image.src, image.alt, image.title, image.from, image.to);
}
Field Description
from / to Document positions for the selected image.
src Serialized image source.
alt Normalized alt text. Empty string when absent.
title Normalized title or null.
previewSrc Browser-only preview URL or data image URL, or null.

Options

const editor = createQalmaEditor({
  plugins: [
    ImagePlugin.configure({
      allowedProtocols: ['http', 'https'],
      allowRelativeImages: true,
      defaultAlt: '',
    }),
  ],
});
Option Default Validation
allowedProtocols ['http', 'https'] Non-empty array of protocol names without colons, all unique.
allowRelativeImages true Boolean. Relative sources are allowed unless they start with //.
defaultAlt '' String.

src values are trimmed. Empty values are rejected. Protocol-relative URLs such as //cdn.example.com/image.png are rejected when no explicit protocol is present.

Upload pattern

The docs playground keeps upload handling in the app. It creates a temporary object URL for immediate preview, while storing a stable application URL in src.

insertUploadedImage(file: File): void {
  const previewSrc = URL.createObjectURL(file);

  this.editor.execute('insertImage', {
    src: `/uploads/${encodeURIComponent(file.name)}`,
    alt: file.name.replace(/\.[^.]+$/, '').replace(/[-_]+/g, ' '),
    title: file.name,
    previewSrc,
  });
}

previewSrc is accepted only when it starts with blob: or data:image/. Serialization writes the real src, alt, and optional title; it does not write previewSrc.

Styling

The node serializes as inline <img>. Style it from your app.

qalma-content .ProseMirror img {
  max-width: 100%;
  height: auto;
  border-radius: 0.5rem;
}

qalma-content .ProseMirror .ProseMirror-selectednode {
  outline: 2px solid var(--accent);
}