DocMosaicdocs
Examples

next/image renderer

Replace the default <img> with next/image via EditorConfigProvider for automatic optimization.

Editor.Section renders images with a plain <img> tag by default. In Next.js apps you almost always want next/image for automatic resizing, lazy loading, and blur placeholders. EditorConfigProvider is the injection point - pass an imageRenderer and every image section renders through it.

Code

'use client';

import Image from 'next/image';
import { Editor, EditorConfigProvider, type ImageRenderer } from '@docmosaic/react';
import '@docmosaic/react/styles.css';

const NextImageRenderer: ImageRenderer = ({ src, alt, width, height, style, className }) => (
    <Image
        src={src}
        alt={alt ?? ''}
        width={width ?? 0}
        height={height ?? 0}
        style={style}
        className={className}
        // Data URLs (in-browser uploads) skip the optimization proxy.
        unoptimized={src.startsWith('data:')}
    />
);

export default function NextImageEditor() {
    return (
        <Editor.Root>
            <EditorConfigProvider value={{ imageRenderer: NextImageRenderer }}>
                <Editor.Properties />
                <Editor.Toolbar />
                <Editor.Pages />
                <Editor.Canvas>
                    <Editor.Section />
                </Editor.Canvas>
            </EditorConfigProvider>
        </Editor.Root>
    );
}

The renderer signature matches a subset of <img> props plus width / height. Override it once at the boundary and every section, page background, and preview thumbnail picks it up.

DocMosaic's image uploads land as data URLs (no server, no upload pipeline). next/image can't proxy data URLs through its optimizer, so the renderer passes unoptimized for them. Skip this and you'll get a runtime error on the first user upload.

When this matters

  • Marketing pages with CDN-hosted reference images - next/image resizes them per breakpoint.
  • Authenticated assets - sign the URL before rendering by intercepting src in the renderer.
  • Cloudinary / Imgix / Cloudflare Images - use their loader and the editor doesn't have to know.