diff --git a/swh/web/browse/views/content.py b/swh/web/browse/views/content.py
index fa646f904f6dda751cb7434a31bbb266308200c5..d60652b7fc39b90ea057b0d08c9b3edd7c028208 100644
--- a/swh/web/browse/views/content.py
+++ b/swh/web/browse/views/content.py
@@ -180,5 +180,6 @@ def content_display(request, query_string):
                    'top_right_link_text': mark_safe(
                        '<i class="fa fa-file-text fa-fw" aria-hidden="true">'
                        '</i>Raw File'),
-                   'origin_context': None
+                   'origin_context': None,
+                   'vault_cooking': None
                    })
diff --git a/swh/web/browse/views/directory.py b/swh/web/browse/views/directory.py
index d3b9b38284b7d9abc18aa9922dc285479ae5be7d..f1162a7670d69723ce1c89c8b9b95dc620afdcb1 100644
--- a/swh/web/browse/views/directory.py
+++ b/swh/web/browse/views/directory.py
@@ -88,6 +88,13 @@ def directory_browse(request, sha1_git, path=None):
                     'number of subdirectories': len(dirs),
                     'sum of regular file sizes': sum_file_sizes}
 
+    vault_cooking = {
+        'directory_context': True,
+        'directory_id': sha1_git,
+        'revision_context': False,
+        'revision_id': None
+    }
+
     return render(request, 'directory.html',
                   {'empty_browse': False,
                    'heading': 'Directory information',
@@ -103,4 +110,5 @@ def directory_browse(request, sha1_git, path=None):
                    'top_right_link_text': None,
                    'readme_name': readme_name,
                    'readme_url': readme_url,
-                   'origin_context': None})
+                   'origin_context': None,
+                   'vault_cooking': vault_cooking})
diff --git a/swh/web/browse/views/origin.py b/swh/web/browse/views/origin.py
index 76008fe753367d8cf22b89a377f9cb14c84ab26e..7ed233ccc5383fa8f2496cb2476f2d1d4c14f8de 100644
--- a/swh/web/browse/views/origin.py
+++ b/swh/web/browse/views/origin.py
@@ -309,6 +309,13 @@ def origin_directory_browse(request, origin_type, origin_url,
                     'revision id': revision_id,
                     'browse revision url': browse_rev_url}
 
+    vault_cooking = {
+        'directory_context': True,
+        'directory_id': sha1_git,
+        'revision_context': True,
+        'revision_id': revision_id
+    }
+
     return render(request, 'directory.html',
                   {'empty_browse': False,
                    'heading': 'Directory information',
@@ -327,7 +334,8 @@ def origin_directory_browse(request, origin_type, origin_url,
                     ),
                    'readme_name': readme_name,
                    'readme_url': readme_url,
-                   'origin_context': origin_context})
+                   'origin_context': origin_context,
+                   'vault_cooking': vault_cooking})
 
 
 @browse_route(r'origin/(?P<origin_type>[a-z]+)/url/(?P<origin_url>.+)/visit/(?P<timestamp>.+)/content/(?P<path>.+)/', # noqa
@@ -461,7 +469,9 @@ def origin_content_display(request, origin_type, origin_url, path,
                    'top_right_link_text': mark_safe(
                        '<i class="fa fa-file-text fa-fw" aria-hidden="true">'
                        '</i>Raw File'),
-                   'origin_context': origin_context})
+                   'origin_context': origin_context,
+                   'vault_cooking': None
+                   })
 
 
 def _gen_directory_link(url_args, query_params, link_text):
@@ -595,7 +605,8 @@ def origin_log_browse(request, origin_type, origin_url, timestamp=None):
                    'top_right_link': None,
                    'top_right_link_text': None,
                    'include_top_navigation': True,
-                   'origin_context': origin_context})
+                   'origin_context': origin_context,
+                   'vault_cooking': None})
 
 
 @browse_route(r'origin/(?P<origin_type>[a-z]+)/url/(?P<origin_url>.+)/visit/(?P<timestamp>.+)/branches/', # noqa
@@ -747,7 +758,8 @@ def origin_releases_browse(request, origin_type, origin_url, timestamp=None):
                    'displayed_releases': displayed_releases,
                    'prev_releases_url': prev_releases_url,
                    'next_releases_url': next_releases_url,
-                   'origin_context': origin_context})
+                   'origin_context': origin_context,
+                   'vault_cooking': None})
 
 
 @browse_route(r'origin/(?P<origin_type>[a-z]+)/url/(?P<origin_url>.+)/',
@@ -826,7 +838,8 @@ def origin_browse(request, origin_type=None, origin_url=None):
                    'visits_splitted': visits_splitted,
                    'origin_info': origin_info,
                    'browse_url_base': '/browse/origin/%s/url/%s/' %
-                   (origin_type, origin_url)})
+                   (origin_type, origin_url),
+                   'vault_cooking': None})
 
 
 @browse_route(r'origin/search/(?P<url_pattern>.+)/',
diff --git a/swh/web/browse/views/person.py b/swh/web/browse/views/person.py
index 1ab88143b28c74160485879bcfadee165231ae63..49959b974fcb7b0d55428469e3ba764b5db8c54b 100644
--- a/swh/web/browse/views/person.py
+++ b/swh/web/browse/views/person.py
@@ -38,4 +38,5 @@ def person_browse(request, person_id):
                    'top_panel_collapsible': False,
                    'top_panel_text': 'SWH object: Person',
                    'swh_object_metadata': person,
-                   'main_panel_visible': False})
+                   'main_panel_visible': False,
+                   'vault_cooking': None})
diff --git a/swh/web/browse/views/revision.py b/swh/web/browse/views/revision.py
index c9462ea198a2644fb3ba7e169e38742f287c1ee5..60c6db31895bcf6a48bcc87dc306670ad9aa91e8 100644
--- a/swh/web/browse/views/revision.py
+++ b/swh/web/browse/views/revision.py
@@ -165,6 +165,12 @@ def revision_browse(request, sha1_git):
                                query_params=query_params)
 
     history_url = get_revision_log_url(sha1_git, origin_context)
+    vault_cooking = {
+        'directory_context': True,
+        'directory_id': dir_id,
+        'revision_context': True,
+        'revision_id': sha1_git
+    }
 
     return render(request, 'revision.html',
                   {'empty_browse': False,
@@ -188,7 +194,8 @@ def revision_browse(request, sha1_git):
                    'top_right_link_text': mark_safe(
                        '<i class="fa fa-history fa-fw" aria-hidden="true"></i>'
                        'History'
-                    )})
+                    ),
+                   'vault_cooking': vault_cooking})
 
 
 NB_LOG_ENTRIES = 20
@@ -263,4 +270,5 @@ def revision_log_browse(request, sha1_git):
                    'top_right_link': None,
                    'top_right_link_text': None,
                    'include_top_navigation': False,
-                   'origin_context': None})
+                   'origin_context': None,
+                   'vault_cooking': None})
diff --git a/swh/web/static/css/style.css b/swh/web/static/css/style.css
index 1e5746abb4a7903283076db6cb7b83b53c2971ae..40d7c31c1a51c7a7ef4f69c27e6776cf04810788 100644
--- a/swh/web/static/css/style.css
+++ b/swh/web/static/css/style.css
@@ -457,6 +457,11 @@ fieldset[disabled] .btn-swh.active {
 
 .swh-table {
     border-bottom: none !important;
+    margin-bottom: 0px !important;
+}
+
+.swh-table td {
+    vertical-align: middle !important;
 }
 
 .swh-counter {
@@ -508,6 +513,15 @@ fieldset[disabled] .btn-swh.active {
     border: none;
 }
 
+.popover {
+    max-width: 100%;
+}
+
+.btn-swh-vault {
+    border-top-right-radius: 4px !important;
+    border-bottom-right-radius: 4px !important;
+}
+
 .pager a {
     outline: none;
 }
@@ -608,4 +622,23 @@ fieldset[disabled] .btn-swh.active {
     transform: rotate(45deg);
     -webkit-transform: rotate(45deg);
     z-index: 2000;
-  }
\ No newline at end of file
+  }
+
+  .modal {
+    text-align: center;
+    padding: 0!important;
+  }
+
+  .modal:before {
+    content: '';
+    display: inline-block;
+    height: 100%;
+    vertical-align: middle;
+    margin-right: -4px;
+  }
+
+  .modal-dialog {
+    display: inline-block;
+    text-align: left;
+    vertical-align: middle;
+  }
diff --git a/swh/web/templates/browse.html b/swh/web/templates/browse.html
index 418db6613901d588655282cd3c88f92c8d3b58c4..16ab8f396fcb5d7d9f1958bbb9d55961f03012ef 100644
--- a/swh/web/templates/browse.html
+++ b/swh/web/templates/browse.html
@@ -11,6 +11,9 @@
     <li>
       <a  href="#help" data-toggle="tab" style="outline:none;">Help</a>
     </li>
+    <li>
+      <a  href="#vault" data-toggle="tab" style="outline:none;">Vault</a>
+    </li>
     <li>
       <a  href="#browse" data-toggle="tab" style="outline:none;">Browse</a>
     </li>
@@ -31,6 +34,10 @@
       {% include "includes/browse-help.html" %}
     </div>
 
+    <div class="tab-pane" id="vault">
+      {% include "includes/vault-ui.html" %}
+    </div>
+
     <div class="tab-pane" id="browse">
 
       {% if empty_browse %}
@@ -110,26 +117,55 @@
 
   <script>
 
+    var browse_tabs_hash = ["#browse", "#search", "#help", "#vault"];
+
     function removeHash () {
       history.replaceState("", document.title, window.location.pathname + window.location.search);
     }
 
-    var browse_tabs_hash = ["#browse", "#search", "#help"];
+    function show_tab(hash) {
+      $('.navbar-nav.swh-browse-nav a[href="' + hash + '"]').tab('show');
+    }
 
-    // Javascript to enable link to tab
     function show_requested_tab() {
       var hash = window.location.hash;
       if (hash && browse_tabs_hash.indexOf(hash) == -1) {
         return;
       }
       if (hash) {
-        $('.navbar-nav.swh-browse-nav a[href="' + hash + '"]').tab('show');
+        show_tab(hash);
       } else {
-        $('.navbar-nav.swh-browse-nav a[href="#browse"]').tab('show');
+        show_tab('#browse');
       }
-        window.scrollTo(0, 0);
     }
 
+    $('[data-toggle=popover]:not([data-popover-content])').popover();
+    $('[data-toggle=popover][data-popover-content]').popover({
+        html : true,
+        container: 'body',
+        trigger: 'focus',
+        content: function() {
+          var content = $(this).attr("data-popover-content");
+          return $(content).children(".popover-body").html();
+        },
+        title: function() {
+          var title = $(this).attr("data-popover-content");
+          return $(title).children(".popover-heading").html();
+        }
+    }).click(function(e) {
+      e.preventDefault();
+    });;
+
+    // Change hash for page reload
+    $('.nav-tabs a').on('shown.bs.tab', function (e) {
+      if (e.target.hash != '#browse') {
+        window.location.hash = e.target.hash;
+      } else {
+        $('.navbar-nav.swh-browse-nav a[href="#browse"]').tab('show');
+      }
+      window.scrollTo(0, 0);
+    });
+
     // show requested tab when loading the page
     $(document).ready(function() {
 
diff --git a/swh/web/templates/includes/top-navigation.html b/swh/web/templates/includes/top-navigation.html
index 629e65a404b32a1c945a0e7fda9cf53613b8c5ea..0e6377c8e325e5c9b08538d8bee88b2086dfeeb1 100644
--- a/swh/web/templates/includes/top-navigation.html
+++ b/swh/web/templates/includes/top-navigation.html
@@ -1,3 +1,4 @@
+{% load swh_templatetags %}
 
 <div class="swh-browse-top-navigation">
   {% if origin_context and origin_context.branch %}
@@ -61,9 +62,12 @@
     </div>
   {% endif %}
 
-  {% if top_right_link %}
-    <a href="{{ top_right_link | safe }}" class="btn btn-md btn-swh pull-right" role="button">{{ top_right_link_text }}</a>
-  {% endif %}
+  <div class="btn-group pull-right">
+    {% if top_right_link %}
+      <a href="{{ top_right_link | safe }}" class="btn btn-md btn-swh" role="button">{{ top_right_link_text }}</a>
+    {% endif %}
+    {% include "includes/vault-create-tasks.html" %}
+  </div>
 
   {% include "includes/breadcrumbs.html" %}
 
diff --git a/swh/web/templates/includes/vault-create-tasks.html b/swh/web/templates/includes/vault-create-tasks.html
new file mode 100644
index 0000000000000000000000000000000000000000..c04703cb2f78005beb2adaafd87b3ea071960e92
--- /dev/null
+++ b/swh/web/templates/includes/vault-create-tasks.html
@@ -0,0 +1,157 @@
+{% if vault_cooking %}
+  <a class="btn btn-md btn-swh btn-swh-vault" data-placement="bottom" data-popover-content="#vault-popover" data-toggle="popover" href="#" tabindex="0">
+    <i class="fa fa-download fa-fw" aria-hidden="true"></i>Download
+  </a>
+  <div class="hidden" id="vault-popover">
+    <div class="popover-heading">
+      Request download from the Software Heritage Vault
+    </div>
+    <div class="popover-body">
+      <div class="btn-group-vertical">
+        {% if vault_cooking.directory_context %}
+          <button id="vault-cook-directory" type="button" class="btn btn-md btn-swh" data-toggle="modal" data-target="#vault-cook-directory-modal">Cook a standard archive from the current directory</button>
+        {% endif %}
+        {% if vault_cooking.revision_context %}
+          <button id="vault-cook-revision" type="button" class="btn btn-md btn-swh" data-toggle="modal" data-target="#vault-cook-revision-modal">Cook a git fast-import archive from the current revision</button>
+        {% endif %}
+      </div>
+    </div>
+  </div>
+  <div class="modal fade" id="vault-cook-directory-modal" tabindex="-1" role="dialog" aria-labelledby="vault-cook-directory-modal-label" aria-hidden="true">
+    <div class="modal-dialog">
+      <div class="modal-content">
+        <div class="modal-header">
+          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+          <h4 class="modal-title" id="vault-cook-directory-modal-label">Cook and download a directory from the Software Heritage Vault</h4>
+        </div>
+        <div class="modal-body">
+          <p>
+            You have requested the cooking of the directory with identifier <strong>{{ vault_cooking.directory_id }}</strong>
+            into a standard tar.gz archive.
+          </p>
+          <p>
+            Are you sure you want to continue ?
+          </p>
+          <form>
+            <div class="form-group">
+              <label for="email">(Optional) Send download link once it is available to that email address:</label>
+              <input type="email" class="form-control" id="swh-vault-directory-email">
+            </div>
+          </form>
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-md btn-swh" data-dismiss="modal">Cancel</button>
+          <button type="button" class="btn btn-md btn-swh" onclick="vault_cook_directory_archive()">Ok</button>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="modal fade" id="vault-cook-revision-modal" tabindex="-1" role="dialog" aria-labelledby="vault-cook-revision-modal-label" aria-hidden="true">
+    <div class="modal-dialog">
+      <div class="modal-content">
+        <div class="modal-header">
+          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+          <h4 class="modal-title" id="vault-cook-revision-modal-label">Cook and download a revision from the Software Heritage Vault</h4>
+        </div>
+        <div class="modal-body">
+          <p>
+            You have requested the cooking of the revision with identifier <strong>{{ vault_cooking.revision_id }}</strong>
+            into a git fast-import archive.
+          </p>
+          <p>
+            Are you sure you want to continue ?
+          </p>
+          <form>
+            <div class="form-group">
+              <label for="email">(Optional) Send download link once it is available to that email address:</label>
+              <input type="email" class="form-control" id="swh-vault-revision-email">
+            </div>
+          </form>
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-md btn-swh" data-dismiss="modal">Cancel</button>
+          <button type="button" class="btn btn-md btn-swh" onclick="vault_cook_revision_archive()">Ok</button>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="modal fade" id="invalid-email-modal" tabindex="-1" role="dialog" aria-labelledby="invalid-email-modal-label" aria-hidden="true">
+    <div class="modal-dialog">
+      <div class="modal-content">
+        <div class="modal-header">
+          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+          <h4 class="modal-title" id="invalid-email-modal-label">Invalid Email !</h4>
+        </div>
+        <div class="modal-body">
+          <p>The provided email is not well-formed.</p>
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-md btn-swh" data-dismiss="modal">Ok</button>
+        </div>
+      </div>
+    </div>
+  </div>
+  <script>
+    var cook_dir_url = "{% url 'vault-cook-directory' 'ffff' %}";
+    var cook_rev_url = "{% url 'vault-cook-revision_gitfast' 'ffff' %}";
+    function add_vault_cooking_task(cooking_task) {
+      var vault_cooking_tasks = JSON.parse(sessionStorage.getItem("swh-vault-cooking-tasks"));
+      if (!vault_cooking_tasks) {
+        vault_cooking_tasks = [];
+      }
+      if (vault_cooking_tasks.find(function(val) {
+          return val.object_type == cooking_task.object_type &&
+                  val.object_id == cooking_task.object_id}) == undefined) {
+        var cooking_url;
+        if (cooking_task.object_type == 'directory') {
+          cooking_url = cook_dir_url.replace('ffff', cooking_task.object_id);
+        } else {
+          cooking_url = cook_rev_url.replace('ffff', cooking_task.object_id);
+        }
+        if (cooking_task.email) {
+          cooking_url += "?email=" + cooking_task.email;
+        }
+        $.ajax({
+          url : cooking_url,
+          type : 'POST',
+          success: function() {
+            vault_cooking_tasks.push(cooking_task);
+            sessionStorage.setItem("swh-vault-cooking-tasks", JSON.stringify(vault_cooking_tasks));
+            show_tab('#vault');
+          }
+        });
+      }
+    }
+    function validateEmail(email) {
+      var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+      return re.test(String(email).toLowerCase());
+    }
+    function vault_cook_directory_archive() {
+      var email = $('#swh-vault-directory-email').val().trim();
+      if (!email || validateEmail(email)) {
+        $('#vault-cook-directory-modal').modal('hide');
+        var cooking_task = {'object_type': 'directory',
+                            'object_id': '{{ vault_cooking.directory_id }}',
+                            'email': email,
+                            'status': 'new'};
+        add_vault_cooking_task(cooking_task);
+
+      } else {
+        $('#invalid-email-modal').modal('show');
+      }
+    }
+    function vault_cook_revision_archive() {
+      var email = $('#swh-vault-revision-email').val().trim();
+      if (!email || validateEmail(email)) {
+        $('#vault-cook-revision-modal').modal('hide');
+        var cooking_task = {'object_type': 'revision',
+                            'object_id': '{{ vault_cooking.revision_id }}',
+                            'email': email,
+                            'status': 'new'};
+        add_vault_cooking_task(cooking_task);
+      } else {
+        $('#invalid-email-modal').modal('show');
+      }
+    }
+  </script>
+{% endif %}
\ No newline at end of file
diff --git a/swh/web/templates/includes/vault-ui.html b/swh/web/templates/includes/vault-ui.html
new file mode 100644
index 0000000000000000000000000000000000000000..c0dc1d03d020ed0a113e1541901595a96062439b
--- /dev/null
+++ b/swh/web/templates/includes/vault-ui.html
@@ -0,0 +1,142 @@
+{% load static %}
+
+<div class="panel panel-default" style="overflow-x: auto;">
+  <div class="panel-heading">
+      <h2>Download content from the Software Heritage Vault</h2>
+  </div>
+  <div class="panel-body">
+    <p>
+      This interface enables to track the status of the different Software Heritage
+      Vault cooking tasks created during the current browsing session.
+    </p>
+    <p>
+      Once a cooking task is finished, a link will be made available in order to
+      download the associated archive.
+    </p>
+    <div class="table-responsive">
+      <table class="table swh-table" id="vault-cooking-tasks">
+        <thead>
+          <tr>
+            <th>Object type</th>
+            <th>Object id</th>
+            <th>Email notification</th>
+            <th>Cooking status</th>
+            <th style="width: 320px"></th>
+          </tr>
+        </thead>
+        <tbody></tbody>
+      </table>
+    </div>
+  </div>
+</div>
+
+<script>
+  var cook_dir_url = "{% url 'vault-cook-directory' 'ffff' %}";
+  var cook_rev_url = "{% url 'vault-cook-revision_gitfast' 'ffff' %}";
+  var browse_dir_url = "{% url 'browse-directory' 'ffff' %}";
+  var browse_rev_url = "{% url 'browse-revision' 'ffff' %}";
+
+  var progress = '<div class="progress" style="margin-bottom: 0px;"> \
+                    <div class="progress-bar progress-bar-success progress-bar-striped" \
+                         role="progressbar" aria-valuenow="100" aria-valuemin="0" \
+                         aria-valuemax="100" style="width: 100%;height: 100%;"> \
+                    </div> \
+                  </div>';
+
+  function check_vault_cooking_tasks() {
+    var vault_cooking_tasks = JSON.parse(sessionStorage.getItem("swh-vault-cooking-tasks"));
+    if (!vault_cooking_tasks) {
+      return;
+    }
+    var cooking_urls = [];
+    var tasks = {};
+    for (var i = 0 ; i < vault_cooking_tasks.length ; ++i) {
+      var cooking_task = vault_cooking_tasks[i];
+      tasks[cooking_task.object_id] = cooking_task;
+      var cooking_url;
+      if (cooking_task.object_type == 'directory') {
+        cooking_url = cook_dir_url.replace('ffff', cooking_task.object_id);
+      } else {
+        cooking_url = cook_rev_url.replace('ffff', cooking_task.object_id);
+      }
+      if (cooking_task.status != 'done' && cooking_task.status != 'failed') {
+        cooking_urls.push($.ajax(cooking_url));
+      }
+    }
+    $.when.apply($, cooking_urls).then(function() {
+      $("#vault-cooking-tasks tbody tr").remove();
+      var table = $("#vault-cooking-tasks tbody");
+      for (var i = 0 ; i < cooking_urls.length ; ++i) {
+        var resp;
+        if (cooking_urls.length == 1) {
+          resp = arguments[i];
+        } else {
+          resp = arguments[i][0];
+        }
+        var cooking_task = tasks[resp.obj_id];
+        cooking_task.status = resp.status;
+        cooking_task.fetch_url = resp.fetch_url;
+      }
+      for (var i = 0 ; i < vault_cooking_tasks.length ; ++i) {
+        var cooking_task = vault_cooking_tasks[i];
+        var browse_url;
+        if (cooking_task.object_type == 'directory') {
+          browse_url = browse_dir_url.replace('ffff', cooking_task.object_id);
+        } else {
+          browse_url = browse_rev_url.replace('ffff', cooking_task.object_id);
+        }
+
+        var progress_bar = $.parseHTML(progress)[0];
+        var progress_bar_content = $(progress_bar).find('.progress-bar');
+        if (cooking_task.status == 'failed') {
+          progress_bar_content.css('background-image', 'none');
+          progress_bar_content.css('background-color', 'red');
+        }
+        progress_bar_content.text(cooking_task.status);
+        if (cooking_task.status == 'pending') {
+          progress_bar_content.addClass('active');
+        } else if (cooking_task.status == 'done') {
+          progress_bar_content.removeClass('progress-bar-striped');
+        }
+        var table_row;
+        if (cooking_task.object_type == 'directory') {
+          table_row = '<tr title="Once downloaded, the directory can be extracted with the ' +
+                      'following command:\n\n$ tar xvzf ' + cooking_task.object_id + '.tar.gz">';
+        } else {
+          table_row = '<tr title="Once downloaded, the git repository can be imported with the ' +
+                      'following commands:\n\n$ git init\n$ zcat ' + cooking_task.object_id + '.gitfast.gz | git fast-import">';
+        }
+        if (cooking_task.object_type == 'directory') {
+          table_row += '<td><i class="fa fa-folder fa-fw" aria-hidden="true"></i>directory</td>';
+        } else {
+          table_row += '<td><i class="octicon octicon-git-commit fa-fw"></i>revision</td>';
+        }
+        table_row += '<td><a href="' + browse_url + '">' + cooking_task.object_id + '</a></td>';
+        table_row += '<td>' + (cooking_task.email || 'none') + '</td>';
+        table_row += '<td>' + progress_bar.outerHTML + '</td>';
+        var dl_link = 'Waiting for download link to be available';
+        if (cooking_task.status == 'done') {
+          dl_link = '<a class="btn btn-md btn-swh" href="' + cooking_task.fetch_url +
+                    '"><i class="fa fa-download fa-fw" aria-hidden="true"></i>Download</a>';
+        }
+        table_row += '<td  style="width: 320px">' + dl_link + '</td>';
+        table_row += '</tr>';
+        table.append(table_row);
+      }
+      sessionStorage.setItem("swh-vault-cooking-tasks", JSON.stringify(vault_cooking_tasks));
+      check_vault_id = setTimeout(check_vault_cooking_tasks, polling_interval);
+    });
+  }
+
+  var polling_interval = 5000;
+
+  var check_vault_id = setTimeout(check_vault_cooking_tasks, polling_interval);
+
+  $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
+    if (e.target.text == 'Vault') {
+      clearTimeout(check_vault_id);
+      check_vault_cooking_tasks();
+    }
+  });
+
+</script>
\ No newline at end of file
diff --git a/swh/web/tests/browse/views/test_directory.py b/swh/web/tests/browse/views/test_directory.py
index 42fe069d2ad37cdbd3e5d983dd1eb70866764d70..d9181b58c533482ba5ede7bbb2db16b0b03b4f15 100644
--- a/swh/web/tests/browse/views/test_directory.py
+++ b/swh/web/tests/browse/views/test_directory.py
@@ -81,6 +81,8 @@ class SwhBrowseDirectoryTest(SWHWebTestBase, TestCase):
             self.assertContains(resp, '<a href="%s">%s</a>' %
                                       (dir_url, p['name']))
 
+        self.assertContains(resp, '<button id="vault-cook-directory"')
+
     @patch('swh.web.browse.utils.service')
     @istest
     def root_directory_view(self, mock_service):
diff --git a/swh/web/tests/browse/views/test_origin.py b/swh/web/tests/browse/views/test_origin.py
index fc68019a7e103aae32565fa797a03e9a74f76b0e..09678da808be05951ba406d2c032a58ee7eeef96 100644
--- a/swh/web/tests/browse/views/test_origin.py
+++ b/swh/web/tests/browse/views/test_origin.py
@@ -387,6 +387,8 @@ class SwhBrowseOriginTest(SWHWebTestBase, TestCase):
                         query_params=query_params)
 
             self.assertContains(resp, '<a href="%s">' % root_dir_release_url)
+        self.assertContains(resp, '<button id="vault-cook-directory"')
+        self.assertContains(resp, '<button id="vault-cook-revision"')
 
     @patch('swh.web.browse.utils.get_origin_visits')
     @patch('swh.web.browse.utils.get_origin_visit_occurrences')
diff --git a/swh/web/tests/browse/views/test_revision.py b/swh/web/tests/browse/views/test_revision.py
index d6bb595a4d8f3c49f252d8541272c2715596f4b7..024942f5850dc29cdb6e762875c4e31003c8333e 100644
--- a/swh/web/tests/browse/views/test_revision.py
+++ b/swh/web/tests/browse/views/test_revision.py
@@ -116,6 +116,9 @@ class SwhBrowseRevisionTest(SWHWebTestBase, TestCase):
             self.assertContains(resp, '<a href="%s">%s</a>' %
                                 (parent_url, parent))
 
+        self.assertContains(resp, '<button id="vault-cook-directory"')
+        self.assertContains(resp, '<button id="vault-cook-revision"')
+
     @patch('swh.web.browse.views.revision.service')
     @istest
     def revision_log_browse(self, mock_service):