diff --git a/client/css/tag-input.styl b/client/css/tag-input.styl
index 216f03c2..f7b45dd7 100644
--- a/client/css/tag-input.styl
+++ b/client/css/tag-input.styl
@@ -2,6 +2,15 @@
 
 div.tag-input
     position: relative
+
+    .main-control
+        display: flex
+        input
+            flex: 5
+        button
+            flex: 1
+            margin: 0 0 0 0.5em
+
     ul
         margin-top: 0.2em
     li
diff --git a/client/html/tag_input.tpl b/client/html/tag_input.tpl
index 876e552a..87791289 100644
--- a/client/html/tag_input.tpl
+++ b/client/html/tag_input.tpl
@@ -1,5 +1,8 @@
 <div class='tag-input'>
-    <input type='text' placeholder='type to add…'/>
+    <div class='main-control'>
+        <input type='text' placeholder='type to add…'/>
+        <button>Add</button>
+    </div>
 
     <div class='tag-suggestions'>
         <div class='wrapper'>
diff --git a/client/js/controls/tag_input_control.js b/client/js/controls/tag_input_control.js
index b95fae03..6546fcd8 100644
--- a/client/js/controls/tag_input_control.js
+++ b/client/js/controls/tag_input_control.js
@@ -118,6 +118,8 @@ class TagInputControl extends events.EventTarget {
             'click', e => this._evtToggleSuggestionsPopupOpacityClick(e));
         this._editAreaNode.querySelector('a.close').addEventListener(
             'click', e => this._evtCloseSuggestionsPopupClick(e));
+        this._editAreaNode.querySelector('button').addEventListener(
+            'click', e => this._evtAddTagButtonClick(e));
 
         // show
         this._hostNode.style.display = 'none';
@@ -248,6 +250,11 @@ class TagInputControl extends events.EventTarget {
         this._closeSuggestionsPopup();
     }
 
+    _evtAddTagButtonClick(e) {
+        this.addTag(this._tagInputNode.value, SOURCE_USER_INPUT);
+        this._tagInputNode.value = '';
+    }
+
     _evtToggleSuggestionsPopupOpacityClick(e) {
         e.preventDefault();
         this._toggleSuggestionsPopupOpacity();