diff --git a/static/js/catalog.js b/static/js/catalog.js
new file mode 100644
index 0000000..0a209ee
--- /dev/null
+++ b/static/js/catalog.js
@@ -0,0 +1,38 @@
+var typingTimer;
+var doneTypingInterval = 500;
+
+var app = new Vue({
+    el: '#app',
+    delimiters: ['${', '}'],
+    data: {
+        prevTerms: {},
+        searchTerms: {},
+        hits: {},
+    },
+    methods: {
+        run_search(qid) {
+            var terms = this.searchTerms[qid];
+            if (terms == this.prevTerms[qid]) {
+                return;  // no change
+            }
+            this.prevTerms[qid] = terms;
+            if (terms.length < 3) {
+                this.hits[qid] = [];
+                return;
+            }
+
+            var vm = this;
+
+            fetch(lookup_url + '?terms=' + encodeURI(terms))
+                .then((res) => res.json())
+                .then((data) => {
+                    vm.hits[qid] = data.hits;
+                })
+        },
+        search(event) {
+            var qid = event.target.dataset.qid
+            clearTimeout(typingTimer);
+            typingTimer = setTimeout(this.run_search, doneTypingInterval, qid);
+        }
+    }
+});
diff --git a/templates/catalog.html b/templates/catalog.html
index 47c64e9..2212bf5 100644
--- a/templates/catalog.html
+++ b/templates/catalog.html
@@ -21,8 +21,34 @@
 
 {% block title %}{{ title }}{% endblock %}
 
+{% block style %}
+<style>
+.autocomplete {
+  /*the container must be positioned relative:*/
+  position: relative;
+  display: inline-block;
+}
+
+.autocomplete-items {
+  position: absolute;
+  z-index: 99;
+  /*position the autocomplete items to be the same width as the container:*/
+  top: 100%;
+  left: 0;
+  right: 0;
+}
+.autocomplete-items div {
+  cursor: pointer;
+  background-color: #fff;
+}
+
+
+
+</style>
+{% endblock %}
+
 {% block content %}
-  <div class="p-2">
+  <div class="p-2" id="app">
     <h1>{{ self.title() }}</h1>
     {% for item in items %}
     <div class="card mb-3">
@@ -39,6 +65,25 @@
               </p>
 
               {{ item_detail(item.entity) }}
+
+              <div class="autocomplete w-100">
+                <input class="form-control-lg my-2 search" data-qid="{{item.qid}}" autocomplete="off" @input="search" v-model.trim="searchTerms['{{ item.qid}}']" />
+
+                <div v-if="hits.{{item.qid}} && hits.{{item.qid}}.length" id="item-list" class="autocomplete-items">
+                  <div v-for="hit in hits.{{item.qid}}">
+                    <div>
+                      <a href="#">${ hit.label }</a>
+                      <span v-if="hit.alt_label">(${ hit.alt_label })</span>
+                      &mdash; ${ hit.count } existing paintings
+                      (${ hit.qid })
+                      <a :href="'https://www.wikidata.org/wiki/' + hit.qid">view on Wikidata</a>
+                    </div>
+                    <div v-if="hit.description">
+                      <div class="description">${ hit.description }</div>
+                    </div>
+                  </div> <! -- end for -->
+                </div>
+              </div>
           </div>
         </div>
       </div>
@@ -47,3 +92,11 @@
   </div>
 
 {% endblock %}
+
+{% block script %}
+<script>
+  var lookup_url = {{ url_for('depicts_lookup') | tojson }};
+</script>
+<script src="{{ url_for('static', filename='vue/vue.js') }}"></script>
+<script src="{{ url_for('static', filename='js/catalog.js') }}"></script>
+{% endblock %}