Image upload 

A profile carries at most one image. It is written by two endpoints of its own, uploadImage and removeImage, and never by a save that carries the other fields.

The two endpoints 

Endpoint Request
uploadImage POST with a multipart/form-data body. The file travels in the field tx_modernextbasefrontendedit_ajax[profile][image], the uid of the addressed record in tx_modernextbasefrontendedit_ajax[uid].
removeImage POST with a JSON body, like every other endpoint. Removing an image that is already absent is not an error.

Both require the request token, a logged-in website user and the live workspace, and both answer with the same document every other endpoint answers with — see JSON endpoints.

Exactly one file per request. A request carrying more than one part for the image field is refused with 400 and the error code 1786496006. A request carrying none is refused with 422, keyed under the field name image.

What is accepted 

Rule Value Message id
MIME type image/jpeg, image/png, image/gif, image/webp validation.profile.image.mimeType
File name extension Has to match the detected MIME type validation.profile.image.extension
File size At most 5M validation.profile.image.tooLarge
Width At most 5000 pixels. No lower bound is configured. validation.profile.image.tooWide
Height At most 5000 pixels. No lower bound is configured. validation.profile.image.tooTall

image/svg+xml is deliberately absent from the accepted MIME types.

Two further checks are added by TYPO3 itself and cannot be switched off from here: the file name check, and the consistency check between the file name extension and the detected MIME type. Their messages come from EXT:extbase/Resources/Private/Language/locallang.xlf and are not overridden by this extension.

A rejected upload stores nothing at all — no partial file and no temporary copy. The file has to be chosen again.

Where the files are stored 

One setting decides the target folder.

Setting TypoScript constant Default
modernextbasefrontendedit.imageUploadFolder plugin.tx_modernextbasefrontendedit.settings.imageUploadFolder 1:/user_upload/profiles/

The value has to be a combined storage identifier — a storage uid, a colon and a folder path, as in 1:/user_upload/profiles/. Anything else is refused by the Extbase upload configuration with exception code 1711801071, and the endpoint then answers an exception page instead of JSON. An empty or whitespace-only value falls back to the same default, which is also what applies when no TypoScript reaches the plugin at all.

The folder itself does not have to exist; it is created on the first upload. The storage it names does have to exist.

Uploaded files keep their name and receive a random suffix, and a name that already exists in the target folder is renamed rather than overwritten.

Replacing and removing an image 

Storing a new image does not overwrite the file behind the old one — the new file is written and the reference is repointed at it. The extension then deletes the previous file, but only when nothing else in the installation still points at it. Two sources are consulted, and either one of them keeps the file:

Source Counted
sys_file_reference Every row that is not deleted and points at the file, excluding the profile's own reference. A hidden reference counts — the record it belongs to still owns the file.
sys_refindex Every entry with ref_table = 'sys_file' naming the file, excluding the entry for the profile's own reference. This is what catches usages that no sys_file_reference row covers, such as a t3://file link in rich text.

Remove follows the same path: the reference is cleared, its sys_file_reference row is soft deleted, and the file is deleted under the same condition.

Limits outside this extension 

The 5M bound applies to requests that reach TYPO3. Two limits cut in before that and produce the web server's own answer rather than a JSON body:

Limit Where
upload_max_filesize PHP configuration. A larger file never reaches $_FILES.
post_max_size PHP configuration. It bounds the whole request body, which is the file plus the other multipart fields, so it has to be the larger of the two.
Request body size limit Web server or reverse proxy, for example client_max_body_size in nginx.

Keep all three at or above 5 MB, or lower the extension's own limit to match them, so that the answer a visitor receives is the one this extension produced.