diff --git a/admin-frontend/src/components/create-article-form.js b/admin-frontend/src/components/create-article-form.js
index efda81086b643a19155a715e9d8f27fc91324b5f..733e663166a05ba9363c331dbacecf8d4637b923 100644
--- a/admin-frontend/src/components/create-article-form.js
+++ b/admin-frontend/src/components/create-article-form.js
@@ -1,7 +1,6 @@
 "use strict";
 
 const Article = require("../article");
-const { images_url } = require("../constants");
 const { fetch_post_article, fetch_article, fetch_update_article } = require("../xhr");
 
 class CreateArticleForm {
@@ -23,6 +22,7 @@ class CreateArticleForm {
         const metadata = Object.assign(this.state.output.metadata, {
             [field]: e.target.value,
         });
+
         this.state.output.metadata = metadata;
     }
 
@@ -166,22 +166,26 @@ class CreateArticleForm {
                                 {
                                     tag: "img",
                                     style_rules: { minWidth: "100%", minHeight: "100%" },
-                                    src: img ? `${images_url}/${img}` : "",
+                                    src: img || "",
                                 }
                             ],
                         },
                         {
-                            tag: "input",
-                            type: "text",
-                            placeholder: "image file name",
-                            value: img,
-                            oninput: e => {
+                            tag: "select",
+                            contents: [
+                                { tag: "option", value: "", contents: "choose", disabled: true, selected: !this.state.output.images[i] }
+                            ].concat((this.params.files_index.images || []).map(url => {
+                                return {
+                                    tag: "option",
+                                    value: url,
+                                    selected: this.state.output.images[i] && this.state.output.images[i] === url,
+                                    contents: url.split("/").reverse()[0],
+                                }
+                            })),
+                            onchange: e => {
                                 this.state.output.images[i] = e.target.value;
-                            }
-                        },
-                        {
-                            tag: "button", contents: "OK",
-                            onclick: this.refresh_images.bind(this)
+                                this.refresh_images();
+                            },
                         },
                         {
                             tag: "button", contents: "DEL",
@@ -234,7 +238,7 @@ class CreateArticleForm {
                         return {
                             tag: "img",
                             style_rules: { height: "100px", width: "auto" },
-                            src: `${images_url}/${img}`
+                            src: img
                         }
                     })
                 },
diff --git a/admin-frontend/src/components/manage-files-form.js b/admin-frontend/src/components/manage-files-form.js
new file mode 100644
index 0000000000000000000000000000000000000000..0358cbdf2df3547afa9fa030e76b3793c231f21c
--- /dev/null
+++ b/admin-frontend/src/components/manage-files-form.js
@@ -0,0 +1,54 @@
+"use strict";
+
+const { fetch_post_file } = require("../xhr");
+
+class ManageFilesForm {
+    constructor(params) {
+        this.params = params;
+    }
+
+    render_index_view() {
+        return {
+            tag: "div",
+            contents: Object.entries(this.params.files_index).map(entry => {
+                const [category, urls] = entry;
+                return {
+                    tag: "div",
+                    contents: [
+                        {
+                            tag: "h3",
+                            contents: category
+                        }
+                    ].concat(urls.map(url => {
+                        return { tag: "div", contents: url }
+                    }))
+                }
+            })
+        }
+
+    }
+
+    render() {
+        return {
+            tag: "div",
+            contents: [
+                this.render_index_view(),
+                {
+                    tag: "form",
+                    style_rules: { border: "1px solid black" },
+                    enctype: "multipart/form-data",
+                    onsubmit: function (e) {
+                        e.preventDefault();
+                        fetch_post_file(e.target).then(res => console.log(res)).catch(err => console.log(err));
+                    },
+                    contents: [
+                        { tag: "input", name: "file", type: "file", multiple: true },
+                        { tag: "input", type: "submit" }
+                    ]
+                }
+            ]
+        }
+    }
+}
+
+module.exports = ManageFilesForm;
\ No newline at end of file
diff --git a/admin-frontend/src/components/root.js b/admin-frontend/src/components/root.js
index d07a98cc3abcadebe21d05c0df51fc38d3a000d9..d14afadd7c3a64c59ca1716010000d49f0efeba0 100644
--- a/admin-frontend/src/components/root.js
+++ b/admin-frontend/src/components/root.js
@@ -1,13 +1,39 @@
 
-const { fetch_post_file } = require("../xhr");
+const { fetch_post_file, fetch_static_files_index } = require("../xhr");
 const CreateArticleForm = require("./create-article-form");
+const ManageFilesForm = require("./manage-files-form");
 const UpdateArticleForm = require("./update-article-form");
 
 class RootComponent {
     constructor() {
         this.state = {
-            selected_tab: ""
+            selected_tab: "",
+            loading_index: true,
+            static_files_index: {}
         };
+
+        this.fetch_files_index();
+    }
+
+    build_index_object(files_urls) {
+        return files_urls.reduce((o, url) => {
+            const split_url = url.split("/");
+            const cat = split_url[(split_url[2] === "uploads") ? 3 : 2];
+            o[cat] = o[cat] ? [...o[cat], url] : [url];
+            return o;
+        }, {});
+    }
+
+    fetch_files_index() {
+        fetch_static_files_index()
+            .then(files =>
+                this.state.static_files_index = this.build_index_object(files)
+            )
+            .catch(err => console.log(err))
+            .finally(() => {
+                this.state.loading_index = false;
+                obj2htm.renderCycle();
+            });
     }
 
     handle_nav_click(e) {
@@ -16,11 +42,14 @@ class RootComponent {
     }
 
     render_state() {
+        const files_index = this.state.static_files_index;
         switch (this.state.selected_tab) {
             case "create":
-                return new CreateArticleForm().render();
+                return new CreateArticleForm({ files_index }).render();
             case "update":
-                return new UpdateArticleForm().render();
+                return new UpdateArticleForm({ files_index }).render();
+            case "files":
+                return new ManageFilesForm({ files_index }).render()
             default:
                 return undefined;
         }
@@ -31,19 +60,6 @@ class RootComponent {
             tag: "main",
             contents: [
                 { tag: "h1", contents: "Kuadrado admin panel" },
-                {
-                    tag: "form",
-                    style_rules: { border: "1px solid black" },
-                    enctype: "multipart/form-data",
-                    onsubmit: function (e) {
-                        e.preventDefault();
-                        fetch_post_file(e.target).then(res => console.log(res)).catch(err => console.log(err));
-                    },
-                    contents: [
-                        { tag: "input", name: "file", type: "file", multiple: true },
-                        { tag: "input", type: "submit" }
-                    ]
-                },
                 {
                     tag: "nav",
                     contents: [
@@ -57,6 +73,11 @@ class RootComponent {
                             class: this.state.selected_tab === "update" ? "selected" : "",
                             onclick: this.handle_nav_click.bind(this),
                         },
+                        {
+                            tag: "span", contents: "Manage files", tab_name: "files",
+                            class: this.state.selected_tab === "files" ? "selected" : "",
+                            onclick: this.handle_nav_click.bind(this),
+                        },
                     ],
                 },
                 this.render_state(),
diff --git a/admin-frontend/src/components/update-article-form.js b/admin-frontend/src/components/update-article-form.js
index fb79156892f71fd878a439581271f775034c67a5..047fdbd84bd67dad33ff6cf41fc644c78b182970 100644
--- a/admin-frontend/src/components/update-article-form.js
+++ b/admin-frontend/src/components/update-article-form.js
@@ -5,7 +5,8 @@ const ArticleList = require("./articles-list");
 const CreateArticleForm = require("./create-article-form");
 
 class UpdateArticleForm {
-    constructor() {
+    constructor(params) {
+        this.params = params;
         this.state = {
             search_article_title: "",
             article_to_update: {},
@@ -63,7 +64,8 @@ class UpdateArticleForm {
                     on_article_sent: () => {
                         this.reset();
                         this.articles_list.fetch_list();
-                    }
+                    },
+                    ...this.params
                 }).render()]
                 : []
         }
diff --git a/admin-frontend/src/xhr.js b/admin-frontend/src/xhr.js
index 4255cff70527fd3c46e43c5178131b5cec67b38e..4c360f060046fd4344a1dc8c1001d45503351555 100644
--- a/admin-frontend/src/xhr.js
+++ b/admin-frontend/src/xhr.js
@@ -115,11 +115,23 @@ function fetch_post_file(form) {
             } else {
                 resolve((await res.json()));
             }
-        })
+        }).catch(err => reject(err))
     })
 
 }
 
+function fetch_static_files_index() {
+    return new Promise((resolve, reject) => {
+        fetch("/static-files-index").then(async res => {
+            if (res.status >= 400 && res.status < 600) {
+                reject((await res.text()))
+            } else {
+                resolve((await res.json()));
+            }
+        }).catch(err => reject(err))
+    })
+}
+
 
 module.exports = {
     fetch_article,
@@ -129,4 +141,5 @@ module.exports = {
     fetch_delete_article,
     fetch_all_articles,
     fetch_post_file,
+    fetch_static_files_index,
 }
\ No newline at end of file
diff --git a/mongo/scripts/migration.js b/mongo/scripts/migration.js
index 3db6e73551411471d9e72bae3e3865205c9becf9..5948c3c82cc46f6d14ba6bd9772dfe28ff9527eb 100644
--- a/mongo/scripts/migration.js
+++ b/mongo/scripts/migration.js
@@ -7,12 +7,7 @@ db.auth(adminname, adminpwd);
 
 articles = db.getCollection("articles");
 
-articles.update({},
-    {
-        $set: {
-            "metadata": { "description": "" },
-            "with_static_view": false
-        }
-    },
-    { upsert: false, multi: true }
-);
\ No newline at end of file
+articles.find().forEach(art => {
+    art.images = art.images.map(img => "/assets/images/" + img);
+    articles.save(art);
+});
\ No newline at end of file
diff --git a/src/core/static_files.rs b/src/core/static_files.rs
index 561d400ce0da779f123b8f02c061312bd3e3abe7..e8057dc4666bc65af40d4b3442b8a8932b1811f9 100644
--- a/src/core/static_files.rs
+++ b/src/core/static_files.rs
@@ -39,7 +39,7 @@ impl StaticFilesIndex {
 
     fn _push_path(path: &Path, files: &mut Vec<String>, strip_from: &Path) {
         let push_path = path.strip_prefix(strip_from).unwrap();
-        files.push(push_path.to_str().unwrap().to_owned());
+        files.push(format!("/{}", push_path.to_str().unwrap().to_owned()));
     }
 
     pub fn rebuild(&mut self, env: &Env) {
@@ -54,6 +54,10 @@ impl StaticFilesIndex {
         let strip_from = StaticFilesIndex::get_public_dir(env);
         StaticFilesIndex::_push_path(path, &mut self.0, &strip_from);
     }
+
+    pub fn get_index(&self) -> Vec<String> {
+        self.0.clone()
+    }
 }
 
 #[derive(Debug, PartialEq)]
diff --git a/src/main.rs b/src/main.rs
index 6439d511f3d86874239cc0931331bde66cf37a6d..07ac8b4e0c1822f397e213fc8a5d4a24cccd0a2e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -95,6 +95,7 @@ async fn main() -> std::io::Result<()> {
             .service(get_article)
             .service(get_all_articles)
             .service(post_files)
+            .service(get_static_files_index)
             /////////////////////////////////////////////////////////////////////////////////////////////////////////////
             // STANDARD FILES ///////////////////////////////////////////////////////////////////////////////////////////
             .service(resource("/favicon.ico").route(get().to(favicon)))
diff --git a/src/service/static_files.rs b/src/service/static_files.rs
index c3af8f01937bcf5628cf1332a8bc762ee235e765..96850a27510f6d77f8d0231faa44d8b60c496d47 100644
--- a/src/service/static_files.rs
+++ b/src/service/static_files.rs
@@ -1,6 +1,6 @@
 use crate::{core::static_files::*, middleware::AuthenticatedAdminMiddleware, AppState};
 use actix_multipart::Multipart;
-use actix_web::{post, web::Data, HttpRequest, HttpResponse, Responder};
+use actix_web::{get, post, web::Data, HttpRequest, HttpResponse, Responder};
 use futures::StreamExt;
 use std::{
     fs::{remove_file, File},
@@ -106,6 +106,18 @@ pub async fn post_files(
     HttpResponse::Ok().json(uploaded_filepathes)
 }
 
+#[get("/static-files-index")]
+async fn get_static_files_index(
+    static_files_index: Data<std::sync::Mutex<StaticFilesIndex>>,
+) -> impl Responder {
+    HttpResponse::Ok().json(
+        static_files_index
+            .lock()
+            .expect("Couldn't lock files index")
+            .get_index(),
+    )
+}
+
 // EXAMPLE FROM ACTIX REPO (using threadpool)
 
 // use futures::TryStreamExt;
diff --git a/website/package-lock.json b/website/package-lock.json
index 3f08ae9befb54c6a17edd4637420a954939e7a56..e11bd851006c2450f3d7308fa60f7b4e95f3fbf9 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -1,12 +1,12 @@
 {
     "name": "kuadrado-website",
-    "version": "1.0.4",
+    "version": "1.1.0",
     "lockfileVersion": 2,
     "requires": true,
     "packages": {
         "": {
             "name": "kuadrado-website",
-            "version": "1.0.4",
+            "version": "1.1.0",
             "license": "MIT",
             "dependencies": {
                 "ks-cheap-translator": "^0.1.0",
diff --git a/website/src/article-vew-components/game-article.js b/website/src/article-vew-components/game-article.js
index 94cf298421435785b2af3da1ddce0f98f702a169..d611a779b45dec1c902c0c32b07cc268f31205ff 100644
--- a/website/src/article-vew-components/game-article.js
+++ b/website/src/article-vew-components/game-article.js
@@ -4,7 +4,6 @@ const ImageCarousel = require("../generic-components/image-carousel");
 const { getArticleBody } = require("../lib/article-utils");
 const { fetch_json_or_error_text } = require("../lib/fetch");
 const { MentaloEngine } = require("mentalo-engine");
-const { images_url, data_url } = require("../../constants");
 
 
 class GameArticle {
@@ -41,16 +40,16 @@ class GameArticle {
             tag: "button",
             class: "play-button",
             contents: "▶️&nbsp;&nbsp;" + t("Jouer"),
-            onclick: this.handle_click_play.bind(this, button_data.filename, button_data.engine)
+            onclick: this.handle_click_play.bind(this, button_data.fileurl, button_data.engine)
         };
     }
 
-    load_and_run_mentalo_game(filename, button_element) {
+    load_and_run_mentalo_game(fileurl, button_element) {
         const button_text = button_element.innerHTML;
         button_element.innerHTML = "Loading ...";
         button_element.style.pointerEvents = "none";
 
-        fetch_json_or_error_text(`${data_url}/${filename}`)
+        fetch_json_or_error_text(fileurl)
             .then(game_data => {
                 const container = document.createElement("div");
                 container.style.position = "fixed";
@@ -88,10 +87,10 @@ class GameArticle {
             });
     }
 
-    handle_click_play(filename, engine, e) {
+    handle_click_play(fileurl, engine, e) {
         switch (engine) {
             case "mentalo":
-                this.load_and_run_mentalo_game(filename, e.target);
+                this.load_and_run_mentalo_game(fileurl, e.target);
                 break;
             default:
                 console.log("Error, unkown engine")
@@ -116,7 +115,7 @@ class GameArticle {
                     tag: "div",
                     id: "article-banner",
                     style_rules: {
-                        backgroundImage: `url(${images_url}/${images[0]})`,
+                        backgroundImage: `url(${images[0]})`,
                     },
                     contents: [
                         {
@@ -158,7 +157,7 @@ class GameArticle {
                                 },
                             ],
                         },
-                        trad_ready && new ImageCarousel({ images: images.map(img => `${images_url}/${img}`) }).render(),
+                        trad_ready && new ImageCarousel({ images }).render(),
                         this.details.length > 0 && {
                             tag: "div",
                             class: "article-details",
diff --git a/website/src/article-vew-components/software-article.js b/website/src/article-vew-components/software-article.js
index 0170cba1e127fed4a4ad5d3b82b8f83dd28e9895..38b3d257f35d7f24dfc3b484053c98a0798a95aa 100644
--- a/website/src/article-vew-components/software-article.js
+++ b/website/src/article-vew-components/software-article.js
@@ -1,7 +1,6 @@
 "use strict";
 
 const ImageCarousel = require("../generic-components/image-carousel");
-const { images_url } = require("../../constants");
 const { getArticleBody } = require("../lib/article-utils");
 
 
@@ -35,7 +34,7 @@ class SoftwareArticle {
                     contents: [
                         {
                             tag: "img",
-                            src: `${images_url}/${logo}`
+                            src: logo
                         },
                     ]
                 },
@@ -76,7 +75,7 @@ class SoftwareArticle {
                     tag: "div",
                     class: "article-more",
                     contents: [
-                        trad_ready && screens.length > 0 && new ImageCarousel({ images: screens.map(img => `${images_url}/${img}`) }).render(),
+                        trad_ready && screens.length > 0 && new ImageCarousel({ images: screens }).render(),
                         details.length > 0 && {
                             tag: "div",
                             class: "article-details",
diff --git a/website/src/home-page-components/theme-card.js b/website/src/home-page-components/theme-card.js
index 87f6a2efd1667e05b9dea2a9eb00f01eb94a1b98..75dba51f5a219aa2ace0b96b48e075296b4d81b0 100644
--- a/website/src/home-page-components/theme-card.js
+++ b/website/src/home-page-components/theme-card.js
@@ -1,7 +1,5 @@
 "use strict";
 
-const { images_url } = require("../../constants");
-
 class ThemeCard {
     constructor(props) {
         this.props = props;
@@ -16,7 +14,12 @@ class ThemeCard {
                 {
                     tag: "div",
                     class: "card-img",
-                    contents: [{ tag: "img", alt: `thematic image ${this.props.img.replace(/\.[A-Za-z]+/, "")}`, src: `${images_url}/${this.props.img}` }],
+                    contents: [
+                        {
+                            tag: "img",
+                            alt: `thematic image ${this.props.img.split("/").reverse()[0].replace(/\.[A-Za-z]+/, "")}`,
+                            src: this.props.img
+                        }],
                 },
                 {
                     tag: "div",
diff --git a/website/src/homepage.js b/website/src/homepage.js
index 3aff6801fd4b7b81c90ddbe84413f1e26531c9d8..b6dc91087a6ff045c52150f1c668d36d1f7e1dd1 100644
--- a/website/src/homepage.js
+++ b/website/src/homepage.js
@@ -59,20 +59,20 @@ class HomePage extends WebPage {
                     contents: [
                         {
                             title: t("Jeux"),
-                            img: "game_controller.svg",
+                            img: images_url + "/game_controller.svg",
                             href: "/games/",
                             description:
                                 t("games-description"),
                         },
                         {
                             title: t("Pédagogie"),
-                            img: "brain.svg",
+                            img: images_url + "/brain.svg",
                             href: "/education/",
                             description: t("education-description"),
                         },
                         {
                             title: "Software",
-                            img: "meca_proc.svg",
+                            img: images_url + "/meca_proc.svg",
                             href: "/software-development/",
                             description: t("software-description"),
                         },
diff --git a/website/src/pages/education/components/edu-article.js b/website/src/pages/education/components/edu-article.js
index ab035167a8d5f31ec639d9b53731ba04cb2a4df3..9814af40a414a4ad641eb4d870c4716e3526c58e 100644
--- a/website/src/pages/education/components/edu-article.js
+++ b/website/src/pages/education/components/edu-article.js
@@ -1,6 +1,5 @@
 "use strict";
 
-const { images_url } = require("../../../../constants");
 const ImageCarousel = require("../../../generic-components/image-carousel");
 const { getArticleBody } = require("../../../lib/article-utils");
 
@@ -27,7 +26,7 @@ class EduArticle {
                     tag: "div", class: "edu-art-image",
                     contents: [
                         {
-                            tag: "img", src: `${images_url}/${images[0]}`
+                            tag: "img", src: images[0]
                         }
                     ]
                 },
@@ -45,7 +44,7 @@ class EduArticle {
                 },
                 images.length > 1 && {
                     tag: "div", class: "edu-art-carousel", contents: [
-                        new ImageCarousel({ images: images.map(img => `${images_url}/${img}`) }).render()
+                        new ImageCarousel({ images: images }).render()
                     ]
                 },
                 details.length > 0 && {
diff --git a/website/src/pages/games/components/game-thumb.js b/website/src/pages/games/components/game-thumb.js
index 1ce8674e4e6327847ebdb27c094bee717b656b67..42cc451d54902eb5e97f39b36377e1e9935e4cc6 100644
--- a/website/src/pages/games/components/game-thumb.js
+++ b/website/src/pages/games/components/game-thumb.js
@@ -1,6 +1,5 @@
 "use strict";
 
-const { images_url } = require("../../../../../admin-frontend/src/constants");
 
 class GameThumb {
     constructor(props) {
@@ -21,7 +20,7 @@ class GameThumb {
             target: "_blank",
             class: "game-thumb",
             style_rules: {
-                backgroundImage: `url(${images_url}/${images[0]})`,
+                backgroundImage: `url(${images[0]})`,
             },
             contents: [
                 {
diff --git a/website/src/pages/software-development/components/software-thumb.js b/website/src/pages/software-development/components/software-thumb.js
index 04fbb425bdfec6cbed7976d4a38d1213fad3344b..ad0390f416413355d489fd2fca2a94fb73c38118 100644
--- a/website/src/pages/software-development/components/software-thumb.js
+++ b/website/src/pages/software-development/components/software-thumb.js
@@ -1,6 +1,5 @@
 "use strict";
 
-const { images_url } = require("../../../../../admin-frontend/src/constants");
 
 class SoftwareThumb {
     constructor(props) {
@@ -26,7 +25,7 @@ class SoftwareThumb {
                     class: "software-image",
                     contents: [
                         {
-                            tag: "img", src: `${images_url}/${images[0]}`
+                            tag: "img", src: `${images[0]}`
                         }
                     ]
                 },