diff --git a/src/controllers/ignores/IgnoreModel.cpp b/src/controllers/ignores/IgnoreModel.cpp
index a5b241c5e..f12fdfe6d 100644
--- a/src/controllers/ignores/IgnoreModel.cpp
+++ b/src/controllers/ignores/IgnoreModel.cpp
@@ -29,8 +29,8 @@ void IgnoreModel::getRowFromItem(const IgnorePhrase &item, std::vector<QStandard
 {
     setStringItem(row[0], item.getPattern());
     setBoolItem(row[1], item.isRegex());
-    setBoolItem(row[2], item.caseInsensitive());
-    setBoolItem(row[3], item.isReplace());
+    setBoolItem(row[2], item.isCaseSensitive());
+    setBoolItem(row[3], item.isBlock());
     setStringItem(row[4], item.getReplace());
 }
 
diff --git a/src/controllers/ignores/IgnorePhrase.hpp b/src/controllers/ignores/IgnorePhrase.hpp
index 476e6080f..7fd3ca5e3 100644
--- a/src/controllers/ignores/IgnorePhrase.hpp
+++ b/src/controllers/ignores/IgnorePhrase.hpp
@@ -17,26 +17,26 @@ class IgnorePhrase
 public:
     bool operator==(const IgnorePhrase &other) const
     {
-        return std::tie(this->pattern_, this->isRegex_, this->isReplace_, this->replace_,
-                        this->caseInsensitive_) == std::tie(other.pattern_, other.isRegex_,
-                                                            other.isReplace_, other.replace_,
-                                                            other.caseInsensitive_);
+        return std::tie(this->pattern_, this->isRegex_, this->isBlock_, this->replace_,
+                        this->isCaseSensitive_) == std::tie(other.pattern_, other.isRegex_,
+                                                            other.isBlock_, other.replace_,
+                                                            other.isCaseSensitive_);
     }
 
-    IgnorePhrase(const QString &pattern, bool isRegex, bool isReplace, const QString &replace,
-                 bool caseInsensitive)
+    IgnorePhrase(const QString &pattern, bool isRegex, bool isBlock, const QString &replace,
+                 bool isCaseSensitive)
         : pattern_(pattern)
         , isRegex_(isRegex)
         , regex_(pattern)
-        , isReplace_(isReplace)
+        , isBlock_(isBlock)
         , replace_(replace)
-        , caseInsensitive_(caseInsensitive)
+        , isCaseSensitive_(isCaseSensitive)
     {
-        if (this->caseInsensitive_) {
+        if (this->isCaseSensitive_) {
+            regex_.setPatternOptions(QRegularExpression::UseUnicodePropertiesOption);
+        } else {
             regex_.setPatternOptions(QRegularExpression::CaseInsensitiveOption |
                                      QRegularExpression::UseUnicodePropertiesOption);
-        } else {
-            regex_.setPatternOptions(QRegularExpression::UseUnicodePropertiesOption);
         }
     }
 
@@ -44,11 +44,17 @@ public:
     {
         return this->pattern_;
     }
+
     bool isRegex() const
     {
         return this->isRegex_;
     }
 
+    bool isRegexValid() const
+    {
+        return this->regex_.isValid();
+    }
+
     bool isMatch(const QString &subject) const
     {
         return !this->pattern_.isEmpty() &&
@@ -61,9 +67,9 @@ public:
         return this->regex_;
     }
 
-    bool isReplace() const
+    bool isBlock() const
     {
-        return this->isReplace_;
+        return this->isBlock_;
     }
 
     const QString &getReplace() const
@@ -71,23 +77,23 @@ public:
         return this->replace_;
     }
 
-    bool caseInsensitive() const
+    bool isCaseSensitive() const
     {
-        return this->caseInsensitive_;
+        return this->isCaseSensitive_;
     }
 
     Qt::CaseSensitivity caseSensitivity() const
     {
-        return this->caseInsensitive_ ? Qt::CaseInsensitive : Qt::CaseSensitive;
+        return this->isCaseSensitive_ ? Qt::CaseSensitive : Qt::CaseInsensitive;
     }
 
 private:
     QString pattern_;
     bool isRegex_;
     QRegularExpression regex_;
-    bool isReplace_;
+    bool isBlock_;
     QString replace_;
-    bool caseInsensitive_;
+    bool isCaseSensitive_;
 };
 }  // namespace chatterino
 
@@ -103,9 +109,9 @@ struct Serialize<chatterino::IgnorePhrase> {
 
         AddMember(ret, "pattern", value.getPattern(), a);
         AddMember(ret, "regex", value.isRegex(), a);
-        AddMember(ret, "onlyWord", value.isReplace(), a);
-        AddMember(ret, "replace", value.getReplace(), a);
-        AddMember(ret, "caseInsens", value.caseInsensitive(), a);
+        AddMember(ret, "isBlock", value.isBlock(), a);
+        AddMember(ret, "replaceWith", value.getReplace(), a);
+        AddMember(ret, "caseSensitive", value.isCaseSensitive(), a);
 
         return ret;
     }
@@ -118,22 +124,22 @@ struct Deserialize<chatterino::IgnorePhrase> {
         if (!value.IsObject()) {
             return chatterino::IgnorePhrase(
                 QString(), false, false,
-                ::chatterino::getSettings()->ignoredPhraseReplace.getValue(), false);
+                ::chatterino::getSettings()->ignoredPhraseReplace.getValue(), true);
         }
 
         QString _pattern;
         bool _isRegex = false;
-        bool _isReplace = false;
+        bool _isBlock = false;
         QString _replace;
-        bool _caseInsens = false;
+        bool _caseSens = true;
 
         chatterino::rj::getSafe(value, "pattern", _pattern);
         chatterino::rj::getSafe(value, "regex", _isRegex);
-        chatterino::rj::getSafe(value, "onlyWord", _isReplace);
-        chatterino::rj::getSafe(value, "replace", _replace);
-        chatterino::rj::getSafe(value, "caseInsens", _caseInsens);
+        chatterino::rj::getSafe(value, "isBlock", _isBlock);
+        chatterino::rj::getSafe(value, "replaceWith", _replace);
+        chatterino::rj::getSafe(value, "caseSensitive", _caseSens);
 
-        return chatterino::IgnorePhrase(_pattern, _isRegex, _isReplace, _replace, _caseInsens);
+        return chatterino::IgnorePhrase(_pattern, _isRegex, _isBlock, _replace, _caseSens);
     }
 };
 
diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp
index 73654ae0f..a9337e3f6 100644
--- a/src/providers/twitch/TwitchMessageBuilder.cpp
+++ b/src/providers/twitch/TwitchMessageBuilder.cpp
@@ -56,7 +56,7 @@ bool TwitchMessageBuilder::isIgnored() const
 
     // TODO(pajlada): Do we need to check if the phrase is valid first?
     for (const auto &phrase : app->ignores->phrases.getVector()) {
-        if (!phrase.isReplace() && phrase.isMatch(this->originalMessage_)) {
+        if (phrase.isBlock() && phrase.isMatch(this->originalMessage_)) {
             Log("Blocking message because it contains ignored phrase {}", phrase.getPattern());
             return true;
         }
@@ -152,7 +152,7 @@ MessagePtr TwitchMessageBuilder::build()
     }
 
     // twitch emotes
-    std::vector<std::pair<long, EmoteData>> twitchEmotes;
+    std::vector<std::tuple<long, EmoteData, QString>> twitchEmotes;
 
     iterator = this->tags.find("emotes");
     if (iterator != this->tags.end()) {
@@ -161,32 +161,31 @@ MessagePtr TwitchMessageBuilder::build()
         for (QString emote : emoteString) {
             this->appendTwitchEmote(ircMessage, emote, twitchEmotes);
         }
-
-        std::sort(twitchEmotes.begin(), twitchEmotes.end(),
-                  [](const auto &a, const auto &b) { return a.first < b.first; });
     }
 
     const auto &phrases = app->ignores->phrases.getVector();
     auto removeEmotesInRange = [&twitchEmotes](int pos, int len) mutable {
-        twitchEmotes.erase(
-            std::remove_if(twitchEmotes.begin(), twitchEmotes.end(),
-                           [&pos, &len](const auto &item) {
-                               return ((item.first >= pos) && item.first < (pos + len));
-                           }),
-            twitchEmotes.end());
+        auto it = std::remove_if(
+            twitchEmotes.begin(), twitchEmotes.end(), [&pos, &len](const auto &item) {
+                return ((std::get<0>(item) >= pos) && std::get<0>(item) < (pos + len));
+            });
+
+        std::vector<std::tuple<long, EmoteData, QString>> v(it, twitchEmotes.end());
+        twitchEmotes.erase(it, twitchEmotes.end());
+        return v;
     };
 
     auto shiftIndicesAfter = [&twitchEmotes](int pos, int by) mutable {
         auto it = std::find_if(twitchEmotes.begin(), twitchEmotes.end(),
-                               [&pos](const auto &item) { return item.first >= pos; });
+                               [&pos](const auto &item) { return std::get<0>(item) >= pos; });
         while (it != twitchEmotes.end()) {
-            it->first += by;
+            std::get<0>(*it) += by;
             ++it;
         }
     };
 
     for (const auto &phrase : phrases) {
-        if (!phrase.isReplace()) {
+        if (phrase.isBlock()) {
             continue;
         }
         if (phrase.isRegex()) {
@@ -198,9 +197,23 @@ MessagePtr TwitchMessageBuilder::build()
             int from = 0;
             while ((from = this->originalMessage_.indexOf(regex, from, &match)) != -1) {
                 int len = match.capturedLength();
-                removeEmotesInRange(from, len);
+                auto vret = removeEmotesInRange(from, len);
                 auto mid = this->originalMessage_.mid(from, len);
                 mid.replace(regex, phrase.getReplace());
+
+                // hemirt
+                // doesnt check for own emotes in the Replace part
+                // mb in IgnoredPhrase ??
+
+                for (auto &tup : vret) {
+                    int index = 0;
+                    const auto &emote = std::get<2>(tup);
+                    while ((index = mid.indexOf(emote, index)) != -1) {
+                        std::get<0>(tup) = from + index;
+                        index += emote.size();
+                        twitchEmotes.push_back(tup);
+                    }
+                }
                 this->originalMessage_.replace(from, len, mid);
                 int midsize = mid.size();
                 from += midsize;
@@ -215,8 +228,22 @@ MessagePtr TwitchMessageBuilder::build()
             while ((from = this->originalMessage_.indexOf(pattern, from,
                                                           phrase.caseSensitivity())) != -1) {
                 int len = pattern.size();
-                removeEmotesInRange(from, len);
-                const auto &replace = phrase.getReplace();
+                auto vret = removeEmotesInRange(from, len);
+                auto replace = phrase.getReplace();
+
+                // hemirt
+                // doesnt check for own emotes in the Replace part
+                // mb in IgnoredPhrase ??
+
+                for (auto &tup : vret) {
+                    int index = 0;
+                    const auto &emote = std::get<2>(tup);
+                    while ((index = replace.indexOf(emote, index)) != -1) {
+                        std::get<0>(tup) = from + index;
+                        index += emote.size();
+                        twitchEmotes.push_back(tup);
+                    }
+                }
                 this->originalMessage_.replace(from, len, replace);
                 int replacesize = replace.size();
                 from += replacesize;
@@ -225,6 +252,8 @@ MessagePtr TwitchMessageBuilder::build()
         }
     }
 
+    std::sort(twitchEmotes.begin(), twitchEmotes.end(),
+              [](const auto &a, const auto &b) { return std::get<0>(a) < std::get<0>(b); });
     auto currentTwitchEmote = twitchEmotes.begin();
 
     // words
@@ -238,8 +267,8 @@ MessagePtr TwitchMessageBuilder::build()
             this->action_ ? MessageColor(this->usernameColor_) : MessageColor(MessageColor::Text);
 
         // twitch emote
-        if (currentTwitchEmote != twitchEmotes.end() && currentTwitchEmote->first == i) {
-            auto emoteImage = currentTwitchEmote->second;
+        if (currentTwitchEmote != twitchEmotes.end() && std::get<0>(*currentTwitchEmote) == i) {
+            auto emoteImage = std::get<1>(*currentTwitchEmote);
             this->emplace<EmoteElement>(emoteImage, MessageElement::TwitchEmote);
 
             i += split.length() + 1;
@@ -586,9 +615,9 @@ void TwitchMessageBuilder::parseHighlights()
     }
 }
 
-void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcMessage *ircMessage,
-                                             const QString &emote,
-                                             std::vector<std::pair<long int, EmoteData>> &vec)
+void TwitchMessageBuilder::appendTwitchEmote(
+    const Communi::IrcMessage *ircMessage, const QString &emote,
+    std::vector<std::tuple<long int, EmoteData, QString>> &vec)
 {
     auto app = getApp();
     if (!emote.contains(':')) {
@@ -621,8 +650,8 @@ void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcMessage *ircMessa
 
         QString name = this->originalMessage_.mid(start, end - start + 1);
 
-        vec.push_back(
-            std::pair<long int, EmoteData>(start, app->emotes->twitch.getEmoteById(id, name)));
+        vec.push_back(std::tuple<long int, EmoteData, QString>(
+            start, app->emotes->twitch.getEmoteById(id, name), name));
     }
 }
 
diff --git a/src/providers/twitch/TwitchMessageBuilder.hpp b/src/providers/twitch/TwitchMessageBuilder.hpp
index 22375b5ad..246f3d50f 100644
--- a/src/providers/twitch/TwitchMessageBuilder.hpp
+++ b/src/providers/twitch/TwitchMessageBuilder.hpp
@@ -51,7 +51,7 @@ private:
     void parseHighlights();
 
     void appendTwitchEmote(const Communi::IrcMessage *ircMessage, const QString &emote,
-                           std::vector<std::pair<long, EmoteData>> &vec);
+                           std::vector<std::tuple<long, EmoteData, QString> > &vec);
     bool tryAppendEmote(QString &emoteString);
 
     void appendTwitchBadges();
diff --git a/src/widgets/settingspages/IgnoresPage.cpp b/src/widgets/settingspages/IgnoresPage.cpp
index 743320cc7..a8465a619 100644
--- a/src/widgets/settingspages/IgnoresPage.cpp
+++ b/src/widgets/settingspages/IgnoresPage.cpp
@@ -45,7 +45,7 @@ void addPhrasesTab(LayoutCreator<QVBoxLayout> layout)
 {
     EditableModelView *view =
         layout.emplace<EditableModelView>(getApp()->ignores->createModel(nullptr)).getElement();
-    view->setTitles({"Pattern", "Regex", "Case Insensitive", "Replace", "Pattern"});
+    view->setTitles({"Pattern", "Regex", "Case Sensitive", "Block", "Pattern"});
     view->getTableView()->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
     view->getTableView()->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
 
@@ -56,7 +56,7 @@ void addPhrasesTab(LayoutCreator<QVBoxLayout> layout)
 
     view->addButtonPressed.connect([] {
         getApp()->ignores->phrases.appendItem(IgnorePhrase{
-            "my phrase", false, false, getSettings()->ignoredPhraseReplace.getValue(), false});
+            "my phrase", false, false, getSettings()->ignoredPhraseReplace.getValue(), true});
     });
 }