Quill editor not adding image align attribute
06:05 10 Dec 2025

I have a quill editor instance inside a vue component. It sort of worked fine, until it decided not to work anymore. I noticed the issue on a branch, where I made quite a few changes on the component, but I realised that even on master (in state prior to any of my changes) the issue exists. The problem I'm having is that after I add an image, I resize it, I align it to the center, all looks good in the editor, but when submitting, the content's json does not have a delta element with the align attribute.
This is how I configure that quill instance:

Quill.register('modules/imageDropAndPaste', QuillImageDropAndPaste);
Quill.register('modules/blotFormatter', BlotFormatter);

const custom = ref(['link', 'image', 'video']);
if (props.customToolbar) {
    custom.value = ['link', 'video'];
}
const toolbarOptions = [
    [{ header: [1, 2, 3, 4, false] }],
    [{ size: ['small', false, 'large', 'huge'] }],
    ['bold', 'underline', 'italic', 'strike'],
    [{ align: [] }],
    [{ list: 'bullet' }],
    [{ list: 'ordered' }],
    [{ color: ['#715192', '#52B99E', '#F45E54', '#009BDF', '#FFB81D', '#FE5F8A', '#36558E', '#F4F4F4', '#8D8C8C', '#464646', '#A282C3', '#A3E3D2', '#FFB2AD', '#A3D8E3'] }, { background: ['#715192', '#52B99E', '#F45E54', '#009BDF', '#FFB81D', '#FE5F8A', '#36558E', '#F4F4F4', '#8D8C8C', '#464646', '#A282C3', '#A3E3D2', '#FFB2AD', '#A3D8E3'] }],
    ['blockquote', 'code-block'],
    [{ script: 'sub' }, { script: 'super' }],
    custom.value
];

const commentToolbar = [
    ['bold', 'underline', 'italic'],
    [{ list: 'bullet' }],
    [{ color: ['#715192', '#52B99E', '#F45E54', '#009BDF', '#FFB81D', '#FE5F8A', '#36558E', '#F4F4F4', '#8D8C8C', '#464646', '#A282C3', '#A3E3D2', '#FFB2AD', '#A3D8E3'] }, { background: ['#715192', '#52B99E', '#F45E54', '#009BDF', '#FFB81D', '#FE5F8A', '#36558E', '#F4F4F4', '#8D8C8C', '#464646', '#A282C3', '#A3E3D2', '#FFB2AD', '#A3D8E3'] }],
    ['link']
];

const editor = ref(null);
let quill = null;

const setupQuill = () => {
    const modules = {
        toolbar: { container: props.comment ? commentToolbar : toolbarOptions },
        imageDropAndPaste: {}
    };

    if (!props.readOnly) {
        modules.blotFormatter = {};
    }

    quill = new Quill(editor.value, {
        modules,
        theme: 'snow',
        readOnly: props.readOnly,
        placeholder: props.placeholder
    });

    quill.on('text-change', () => {
        emit('update:modelValue', JSON.stringify(quill.getContents()));
    });

    if (props.twoWayBinding) {
        watch(() => props.modelValue, (newVal) => {
            if (!quill) return;
            const current = JSON.stringify(quill.getContents());

            if (newVal && newVal !== current) {
                quill.setContents(JSON.parse(newVal));
            }
        });
    }

    quill.getModule('toolbar').addHandler('image', () => {
        const input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.setAttribute('accept', 'image/*');
        input.click();
        input.onchange = async () => {
            const file = input.files[0];
            if (file) {
                const previewUrl = URL.createObjectURL(file);

                const range = quill.getSelection();
                quill.insertEmbed(range.index, 'image', previewUrl, 'user');

                //some more logic here
            }
        };
    });

    if (props.modelValue) {
        quill.setContents(JSON.parse(props.modelValue));
    }
};

onMounted(() => {
    const BaseImage = Quill.import('formats/image');

    class ImageBlot extends BaseImage {
        static sanitize(url) {
            if (url.startsWith('blob:')) return url;
            return super.sanitize(url);
        }
    }

    Quill.register(ImageBlot, true);
    if (editor.value) {
        setupQuill();
    }
});

My understanding, that in order to Quill read the image's position correctly, it needs to be set at block level (and this is how it looked before the issue started to kick in), something like this:

{ insert: {image: "url"} }
{ attributes: { align: "center" }, insert: "\n" }

But mine looks like this:

[
    {
        "attributes": {
            "height": "375.6024516480523",
            "width": "465"
        },
        "insert": {
            "image": "url"
        }
    },
    {
        "insert": "\n"
    }
]

It inserts a new line, without the align attribute.

chatgpt suggested that the problem might be that the modules are not compatible with my quill version:

 "quill": "^2.0.2",
 "quill-blot-formatter": "^1.0.5",
 "quill-image-drop-and-paste": "^1.3.0",

Which is a fair point, but it did work before, the dependency wasn't upgraded. The same setup was working yesterday, today it decided not to :) .

javascript quill