           <span className="upper-strut"/>
           <span className="tags">
             {for tag in sortTags message.tags
-              <>
+              <React.Fragment key={tag.key}>
                 <span className="label label-default tag tagWithRemove">
                   {tag.key + ' '}
-                  <span className="tagRemove fas fa-times-circle" aria-label="Remove" data-tag={tag.key}/>
+                  <span className="tagRemove fas fa-times-circle" aria-label="Remove" data-tag={tag.key} onClick={onTagRemove}/>
                 </span>
                 {' '}
-              </>
+              </React.Fragment>
             }
           </span>
           <span className="btn-group">

                  <li className="divider" role="separator"/>
                  {for tag in absentTags
                    <li key={tag.key}>
                      <a className="tagAdd" href="#" data-tag={tag.key}>{tag.key}</a>
                    </li>
                  }
                </>

      Meteor.call 'messageUpdate', messageID,
        title: newTitle
    , idle
  onTagRemove = (e) ->
    e.preventDefault()
    e.stopPropagation()
    tag = e.currentTarget.getAttribute 'data-tag'
    if tag of message.tags
      Meteor.call 'messageUpdate', message._id,
        tags: _.omit message.tags, escapeTag tag
      , (error) ->
        if error
          console.error error
        else
          Meteor.call 'tagDelete', message.group, tag, true
    else
      console.warn "Attempt to delete nonexistant tag '#{tag}' from message #{message._id}"
  onTagAdd = (e) ->
    e.preventDefault()
    e.stopPropagation()
    tag = e.target.getAttribute 'data-tag'
    if tag of message.tags
      console.warn "Attempt to add duplicate tag '#{tag}' to message #{message._id}"
    else
      Meteor.call 'messageUpdate', message._id,
        tags: Object.assign {}, message.tags ? {}, {"#{escapeTag tag}": true}
    dropdownToggle e
  onTagNew = (e) ->
    e.preventDefault()
    e.stopPropagation()
    textTag = $(e.target).parents('form').first().find('.tagAddText')[0]
    tag = textTag.value.trim()
    textTag.value = ''  ## reset custom tag
    if tag
      if tag of message.tags
        console.warn "Attempt to add duplicate tag '#{tag}' to message #{message._id}"
      else
        Meteor.call 'tagNew', message.group, tag, 'boolean'
        Meteor.call 'messageUpdate', message._id,
          tags: Object.assign {}, message.tags ? {}, {"#{escapeTag tag}": true}
    dropdownToggle e
    false  ## prevent form from submitting

  return null unless visible or here
  <div className="panel message #{messagePanelClass message, editing}" data-message={message._id} id={message._id} ref={ref}>
