diff --git a/app/assets/javascripts/admin/plugins/summernote_attachment_upload.js b/app/assets/javascripts/admin/plugins/summernote_attachment_upload.js
index 26c8ec3e320ce4ed344d4c59d75e3d382a74f0d5..3a88d3c026f28f933ef29d5600b7f8e539ac72bd 100644
--- a/app/assets/javascripts/admin/plugins/summernote_attachment_upload.js
+++ b/app/assets/javascripts/admin/plugins/summernote_attachment_upload.js
@@ -1,9 +1,11 @@
-/*global ActiveStorage */
+/*global $, ActiveStorage */
 var SummernoteAttachmentUpload = function (element, file) {
     'use strict';
     this.element = element;
     this.file = file;
     this.directUpload = new ActiveStorage.DirectUpload(file, this.getDirectUploadUrl(), this);
+    this.previewablePattern = /^image(\/(gif|png|jpe?g)|$)/;
+    this.trixAttributes = {};
 };
 
 SummernoteAttachmentUpload.prototype.start = function () {
@@ -17,12 +19,46 @@ SummernoteAttachmentUpload.prototype.directUploadDidComplete = function (error,
         throw new Error('Direct upload failed: ' + error);
     }
 
-    // Insert Blob in Summernote
-    console.log(attributes);
-    console.log({
+    this.trixAttributes = {
+        contentType: attributes.content_type,
+        filename: attributes.filename,
+        filesize: attributes.byte_size,
+        previewable: this.isPreviewable(attributes.content_type),
         sgid: attributes.attachable_sgid,
         url: this.createBlobUrl(attributes.signed_id, attributes.filename)
-    });
+    };
+
+    if (this.trixAttributes.previewable) {
+        this.preloadAndInsertAttachment();
+    } else {
+        this.insertAttachment();
+    }
+};
+
+SummernoteAttachmentUpload.prototype.preloadAndInsertAttachment = function () {
+    'use strict';
+    var objectUrl = URL.createObjectURL(this.file),
+        img = new Image(),
+        that = this;
+
+    img.onload = function () {
+        that.trixAttributes.width = this.width;
+        that.trixAttributes.height = this.height;
+        URL.revokeObjectURL(objectUrl);
+        that.insertAttachment();
+    };
+    img.src = objectUrl;
+};
+
+SummernoteAttachmentUpload.prototype.insertAttachment = function () {
+    'use strict';
+    var attachmentElement = document.createElement('figure');
+    attachmentElement.setAttribute('data-trix-attachment', JSON.stringify(this.trixAttributes));
+
+    // TODO <img> or text
+    attachmentElement.textContent = this.trixAttributes.filename;
+
+    $(this.element).summernote('insertNode', attachmentElement);
 };
 
 SummernoteAttachmentUpload.prototype.createBlobUrl = function (signedId, filename) {
@@ -32,6 +68,11 @@ SummernoteAttachmentUpload.prototype.createBlobUrl = function (signedId, filenam
         .replace(':filename', encodeURIComponent(filename));
 };
 
+SummernoteAttachmentUpload.prototype.isPreviewable = function (contentType) {
+    'use strict';
+    return this.previewablePattern.test(contentType);
+};
+
 SummernoteAttachmentUpload.prototype.getDirectUploadUrl = function () {
     'use strict';
     return this.element.dataset.directUploadUrl;
diff --git a/docs/communication/wysiwyg.md b/docs/communication/wysiwyg.md
index 1d75e03307f059d77d91b439eead7fabc7418b2b..9df2578522b043e5de6080bf1df47890d34b39c9 100644
--- a/docs/communication/wysiwyg.md
+++ b/docs/communication/wysiwyg.md
@@ -90,7 +90,7 @@ Etapes normales :
 -[ ] A l'import d'une image, ajouter l'action-text-attachement autour
 -[x] A l'enregistrement, déshydrater les action-text-attachements
 -[x] A l'édition, réhydrater les action-text-attachements
--[ ] Après l'enregistrement mettre à jour les blobs attachés à l'objet parent (le post, par exemple)
+-[x] Après l'enregistrement mettre à jour les blobs attachés à l'objet parent (le post, par exemple)
 
 Si un programme a 5 champs summernote avec 3 images dans chaque champ, cela fait 15 attachments à lier au programme.
 Si on enlève une image d'un champ, il faut mettre à jour la liste pour avoir les 14 bons attachments.