diff --git a/assets/js/page_image_detail.js b/assets/js/page_image_detail.js
new file mode 100644
index 0000000000000000000000000000000000000000..1e3093d68e7d891ea847b8d39e111085fdcc5dec
--- /dev/null
+++ b/assets/js/page_image_detail.js
@@ -0,0 +1,35 @@
+const fakeTitle = document.querySelector(".title.fake-input[contenteditable]");
+const fakeDescription = document.querySelector(".description.fake-input[contenteditable]");
+
+const actualTitle = document.querySelector(".update-form input[name=title]");
+const actualDescription = document.querySelector(".update-form input[name=description]");
+
+const fakeTitleListener = (event) => {
+    requestAnimationFrame(() => {
+        document.title = event.target.innerText + " | i.k8r";
+        actualTitle.value = fakeTitle.innerText;
+    })
+
+};
+const fakeDescriptionListener = (event) => {
+    requestAnimationFrame(() => {
+        actualDescription.value = fakeDescription.innerText;
+    })
+
+};
+
+// Insert <br> between lines instead of \n for editing
+fakeDescription.innerHTML = "";
+actualDescription.value.split("\n").forEach((line) => {
+    const textNode = document.createTextNode(line);
+    const brNode = document.createElement("br");
+    fakeDescription.appendChild(textNode);
+    fakeDescription.appendChild(brNode);
+});
+fakeDescription.removeChild(fakeDescription.lastChild);
+
+fakeTitle.addEventListener("input", fakeTitleListener);
+fakeTitle.addEventListener("keypress", fakeTitleListener);
+
+fakeDescription.addEventListener("input", fakeDescriptionListener);
+fakeDescription.addEventListener("keypress", fakeDescriptionListener);
\ No newline at end of file
diff --git a/assets/js/page_upload.js b/assets/js/page_upload.js
index f6df5cb8973727f0634282e0d0c208d41cac83c0..5dea72e909cd43e603c8b8d04de265594228fc00 100644
--- a/assets/js/page_upload.js
+++ b/assets/js/page_upload.js
@@ -6,36 +6,57 @@ function postData(url, data) {
         method: 'POST',
         mode: 'cors',
         redirect: 'follow'
-    }).then(response => response.json());
+    }).then(response => response.json())
 }
-const form = document.querySelector('form.upload');
-const element = document.querySelector('form.upload input[type=file]');
-const results = document.querySelector('.uploading.images');
-element.addEventListener('change', () => {
+
+const form = document.querySelector("form.upload");
+const element = document.querySelector("form.upload input[type=file]");
+const results = document.querySelector(".uploading.images");
+element.addEventListener("change", () => {
     for (let file of element.files) {
         const reader = new FileReader();
-        reader.addEventListener('load', e => {
+        reader.addEventListener("load", (e) => {
             const dataUrl = e.target.result;
-            const node = function () {
-                var $$a = document.createElement('div');
-                $$a.setAttribute('class', 'uploading image');
-                return $$a;
-            }.call(this);
-            results.appendChild(node);
+
+            const image_container = document.createElement("div");
+            image_container.classList.add("uploading", "image");
+
+            const image_title = document.createElement("h2");
+            image_title.classList.add("title", "fake-input");
+            image_title.contentEditable = "true";
+            image_title.placeholder = "Description";
+            image_container.appendChild(image_title);
+
+            const image_link = document.createElement("a");
+            image_link.classList.add("image");
+            const image = document.createElement("img");
+            image.src = dataUrl;
+            image_link.appendChild(image);
+            image_container.appendChild(image_link);
+
+            const image_description = document.createElement("p");
+            image_description.classList.add("description", "fake-input");
+            image_description.contentEditable = "true";
+            image_description.placeholder = "Description";
+            image_description.dataset["multiline"] = "true";
+            image_container.appendChild(image_description);
+
+            results.appendChild(image_container);
+
             const data = new FormData();
-            data.append('file', file, file.name);
-            postData('/upload/', data).then(json => {
+            data.append("file", file, file.name);
+
+            postData("/upload/", data).then((json) => {
                 if (json.success) {
-                    node.querySelector('a.image').href = '/' + json.id;
-                    node.querySelector('a.image img').src = '/' + json.id;
+                    image_link.href = "/" + json.id;
+                    image.src = "/" + json.id;
                 } else {
-                    node.insertBefore(function () {
-                        var $$b = document.createElement('div');
-                        $$b.setAttribute('class', 'alert error');
-                        $$b.appendChildren(JSON.stringify(json.errors));
-                        return $$b;
-                    }.call(this), node.querySelector('.description'));
+                    const image_error = document.createElement("div");
+                    image_error.classList.add("alert", "error");
+                    image_error.innerText = JSON.stringify(json.errors);
+                    image_container.insertBefore(image_error, image_description);
                 }
+
                 console.log(json);
             });
         });
diff --git a/assets/js/page_upload.jsx b/assets/js/page_upload.jsx
deleted file mode 100644
index 5dea72e909cd43e603c8b8d04de265594228fc00..0000000000000000000000000000000000000000
--- a/assets/js/page_upload.jsx
+++ /dev/null
@@ -1,65 +0,0 @@
-function postData(url, data) {
-    return fetch(url, {
-        body: data,
-        cache: 'no-cache',
-        credentials: 'same-origin',
-        method: 'POST',
-        mode: 'cors',
-        redirect: 'follow'
-    }).then(response => response.json())
-}
-
-const form = document.querySelector("form.upload");
-const element = document.querySelector("form.upload input[type=file]");
-const results = document.querySelector(".uploading.images");
-element.addEventListener("change", () => {
-    for (let file of element.files) {
-        const reader = new FileReader();
-        reader.addEventListener("load", (e) => {
-            const dataUrl = e.target.result;
-
-            const image_container = document.createElement("div");
-            image_container.classList.add("uploading", "image");
-
-            const image_title = document.createElement("h2");
-            image_title.classList.add("title", "fake-input");
-            image_title.contentEditable = "true";
-            image_title.placeholder = "Description";
-            image_container.appendChild(image_title);
-
-            const image_link = document.createElement("a");
-            image_link.classList.add("image");
-            const image = document.createElement("img");
-            image.src = dataUrl;
-            image_link.appendChild(image);
-            image_container.appendChild(image_link);
-
-            const image_description = document.createElement("p");
-            image_description.classList.add("description", "fake-input");
-            image_description.contentEditable = "true";
-            image_description.placeholder = "Description";
-            image_description.dataset["multiline"] = "true";
-            image_container.appendChild(image_description);
-
-            results.appendChild(image_container);
-
-            const data = new FormData();
-            data.append("file", file, file.name);
-
-            postData("/upload/", data).then((json) => {
-                if (json.success) {
-                    image_link.href = "/" + json.id;
-                    image.src = "/" + json.id;
-                } else {
-                    const image_error = document.createElement("div");
-                    image_error.classList.add("alert", "error");
-                    image_error.innerText = JSON.stringify(json.errors);
-                    image_container.insertBefore(image_error, image_description);
-                }
-
-                console.log(json);
-            });
-        });
-        reader.readAsDataURL(file);
-    }
-});
\ No newline at end of file
diff --git a/templates/image_detail.html b/templates/image_detail.html
index ca3646cf9818455346c7d0fa5643541b0d3cebf5..f89c667149dfd19c64bbda9fa0e60fb362e2cf11 100644
--- a/templates/image_detail.html
+++ b/templates/image_detail.html
@@ -62,42 +62,6 @@
     });
 </script>
 {{if .IsMine}}
-<script>
-    const fakeTitle = document.querySelector(".title.fake-input[contenteditable]");
-    const fakeDescription = document.querySelector(".description.fake-input[contenteditable]");
-
-    const actualTitle = document.querySelector(".update-form input[name=title]");
-    const actualDescription = document.querySelector(".update-form input[name=description]");
-
-    const fakeTitleListener = (event) => {
-        requestAnimationFrame(() => {
-            document.title = event.target.innerText + " | i.k8r";
-            actualTitle.value = fakeTitle.innerText;
-        })
-
-    };
-    const fakeDescriptionListener = (event) => {
-        requestAnimationFrame(() => {
-            actualDescription.value = fakeDescription.innerText;
-        })
-
-    };
-
-    // Insert <br> between lines instead of \n for editing
-    fakeDescription.innerHTML = "";
-    actualDescription.value.split("\n").forEach((line) => {
-        const textNode = document.createTextNode(line);
-        const brNode = document.createElement("br");
-        fakeDescription.appendChild(textNode);
-        fakeDescription.appendChild(brNode);
-    });
-    fakeDescription.removeChild(fakeDescription.lastChild);
-
-    fakeTitle.addEventListener("input", fakeTitleListener);
-    fakeTitle.addEventListener("keypress", fakeTitleListener);
-
-    fakeDescription.addEventListener("input", fakeDescriptionListener);
-    fakeDescription.addEventListener("keypress", fakeDescriptionListener);
-</script>
+<script src="/assets/js/page_image_detail.js"></script>
 {{end}}
 {{end}}