diff --git a/db/patch10.sql b/db/patch10.sql
new file mode 100644
index 000000000..488db1169
--- /dev/null
+++ b/db/patch10.sql
@@ -0,0 +1,19 @@
+-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
+CREATE TABLE tag (
+	id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+	name VARCHAR(255) NOT NULL,
+    color VARCHAR(255) NOT NULL,
+	created_date DATETIME DEFAULT (DATETIME('now')) NOT NULL
+);
+
+CREATE TABLE monitor_tag (
+	id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+	monitor_id INTEGER NOT NULL,
+	tag_id INTEGER NOT NULL,
+	value TEXT,
+	CONSTRAINT FK_tag FOREIGN KEY (tag_id) REFERENCES tag(id) ON DELETE CASCADE ON UPDATE CASCADE,
+	CONSTRAINT FK_monitor FOREIGN KEY (monitor_id) REFERENCES monitor(id) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX monitor_tag_monitor_id_index ON monitor_tag (monitor_id);
+CREATE INDEX monitor_tag_tag_id_index ON monitor_tag (tag_id);
diff --git a/server/database.js b/server/database.js
index 4b3ad443e..7af75423a 100644
--- a/server/database.js
+++ b/server/database.js
@@ -37,7 +37,7 @@ class Database {
      * The finally version should be 10 after merged tag feature
      * @deprecated Use patchList for any new feature
      */
-    static latestVersion = 9;
+    static latestVersion = 10;
 
     static noReject = true;
 
diff --git a/server/model/monitor.js b/server/model/monitor.js
index 89208a3fd..6c4e17eeb 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -32,6 +32,8 @@ class Monitor extends BeanModel {
             notificationIDList[bean.notification_id] = true;
         }
 
+        const tags = await R.getAll("SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [this.id]);
+
         return {
             id: this.id,
             name: this.name,
@@ -52,6 +54,7 @@ class Monitor extends BeanModel {
             dns_resolve_server: this.dns_resolve_server,
             dns_last_result: this.dns_last_result,
             notificationIDList,
+            tags: tags,
         };
     }
 
diff --git a/server/model/tag.js b/server/model/tag.js
new file mode 100644
index 000000000..748280a70
--- /dev/null
+++ b/server/model/tag.js
@@ -0,0 +1,13 @@
+const { BeanModel } = require("redbean-node/dist/bean-model");
+
+class Tag extends BeanModel {
+    toJSON() {
+        return {
+            id: this._id,
+            name: this._name,
+            color: this._color,
+        };
+    }
+}
+
+module.exports = Tag;
diff --git a/server/server.js b/server/server.js
index a0b9a2fbb..003d25ae6 100644
--- a/server/server.js
+++ b/server/server.js
@@ -514,6 +514,22 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
             }
         });
 
+        socket.on("getMonitorList", async (callback) => {
+            try {
+                checkLogin(socket)
+                await sendMonitorList(socket);
+                callback({
+                    ok: true,
+                });
+            } catch (e) {
+                console.error(e)
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
         socket.on("getMonitor", async (monitorID, callback) => {
             try {
                 checkLogin(socket)
@@ -608,6 +624,159 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
             }
         });
 
+        socket.on("getTags", async (callback) => {
+            try {
+                checkLogin(socket)
+
+                const list = await R.findAll("tag")
+
+                callback({
+                    ok: true,
+                    tags: list.map(bean => bean.toJSON()),
+                });
+
+            } catch (e) {
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
+        socket.on("addTag", async (tag, callback) => {
+            try {
+                checkLogin(socket)
+
+                let bean = R.dispense("tag")
+                bean.name = tag.name
+                bean.color = tag.color
+                await R.store(bean)
+
+                callback({
+                    ok: true,
+                    tag: await bean.toJSON(),
+                });
+
+            } catch (e) {
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
+        socket.on("editTag", async (tag, callback) => {
+            try {
+                checkLogin(socket)
+
+                let bean = await R.findOne("monitor", " id = ? ", [ tag.id ])
+                bean.name = tag.name
+                bean.color = tag.color
+                await R.store(bean)
+
+                callback({
+                    ok: true,
+                    tag: await bean.toJSON(),
+                });
+
+            } catch (e) {
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
+        socket.on("deleteTag", async (tagID, callback) => {
+            try {
+                checkLogin(socket)
+
+                await R.exec("DELETE FROM tag WHERE id = ? ", [ tagID ])
+
+                callback({
+                    ok: true,
+                    msg: "Deleted Successfully.",
+                });
+
+            } catch (e) {
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
+        socket.on("addMonitorTag", async (tagID, monitorID, value, callback) => {
+            try {
+                checkLogin(socket)
+
+                await R.exec("INSERT INTO monitor_tag (tag_id, monitor_id, value) VALUES (?, ?, ?)", [
+                    tagID,
+                    monitorID,
+                    value,
+                ])
+
+                callback({
+                    ok: true,
+                    msg: "Added Successfully.",
+                });
+
+            } catch (e) {
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
+        socket.on("editMonitorTag", async (tagID, monitorID, value, callback) => {
+            try {
+                checkLogin(socket)
+
+                await R.exec("UPDATE monitor_tag SET value = ? WHERE tag_id = ? AND monitor_id = ?", [
+                    value,
+                    tagID,
+                    monitorID,
+                ])
+
+                callback({
+                    ok: true,
+                    msg: "Edited Successfully.",
+                });
+
+            } catch (e) {
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
+        socket.on("deleteMonitorTag", async (tagID, monitorID, callback) => {
+            try {
+                checkLogin(socket)
+
+                await R.exec("DELETE FROM monitor_tag WHERE tag_id = ? AND monitor_id = ?", [
+                    tagID,
+                    monitorID,
+                ])
+
+                // Cleanup unused Tags
+                await R.exec("delete from tag where ( select count(*) from monitor_tag mt where tag.id = mt.tag_id ) = 0");
+
+                callback({
+                    ok: true,
+                    msg: "Deleted Successfully.",
+                });
+
+            } catch (e) {
+                callback({
+                    ok: false,
+                    msg: e.message,
+                });
+            }
+        });
+
         socket.on("changePassword", async (password, callback) => {
             try {
                 checkLogin(socket)
diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue
index e72155891..77097dc12 100644
--- a/src/components/MonitorList.vue
+++ b/src/components/MonitorList.vue
@@ -11,6 +11,9 @@
                         <Uptime :monitor="item" type="24" :pill="true" />
                         {{ item.name }}
                     </div>
+                    <div class="tags">
+                        <Tag v-for="tag in item.tags" :key="tag" :item="tag" :size="'sm'" />
+                    </div>
                 </div>
                 <div v-show="$root.userHeartbeatBar == 'normal'" :key="$root.userHeartbeatBar" class="col-6 col-md-4">
                     <HeartbeatBar size="small" :monitor-id="item.id" />
@@ -29,10 +32,13 @@
 <script>
 import HeartbeatBar from "../components/HeartbeatBar.vue";
 import Uptime from "../components/Uptime.vue";
+import Tag from "../components/Tag.vue";
+
 export default {
     components: {
         Uptime,
         HeartbeatBar,
+        Tag,
     },
     props: {
         scrollbar: {
@@ -140,4 +146,11 @@ export default {
 .monitorItem {
     width: 100%;
 }
+
+.tags {
+    padding-left: 62px;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 0;
+}
 </style>
diff --git a/src/components/Tag.vue b/src/components/Tag.vue
new file mode 100644
index 000000000..22ae8c3b0
--- /dev/null
+++ b/src/components/Tag.vue
@@ -0,0 +1,68 @@
+<template>
+    <div class="tag-wrapper rounded d-inline-flex"
+         :class="{ 'px-3': size == 'normal',
+                   'py-1': size == 'normal',
+                   'm-2': size == 'normal',
+                   'px-2': size == 'sm',
+                   'py-0': size == 'sm',
+                   'm-1': size == 'sm',
+         }"
+         :style="{ backgroundColor: item.color, fontSize: size == 'sm' ? '0.7em' : '1em' }"
+    >
+        <span class="tag-text">{{ displayText }}</span>
+        <span v-if="remove != null" class="ps-1 btn-remove" @click="remove(item)">
+            <font-awesome-icon icon="times" />
+        </span>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        item: {
+            type: Object,
+            required: true,
+        },
+        remove: {
+            type: Function,
+            default: null,
+        },
+        size: {
+            type: String,
+            default: "normal",
+        }
+    },
+    computed: {
+        displayText() {
+            if (this.item.value == "") {
+                return this.item.name;
+            } else {
+                return `${this.item.name}: ${this.item.value}`;
+            }
+        }
+    }
+}
+</script>
+
+<style scoped>
+.tag-wrapper {
+    color: white;
+}
+
+.tag-text {
+    padding-bottom: 1px !important;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+}
+
+.btn-remove {
+    font-size: 0.9em;
+    line-height: 24px;
+    opacity: 0.3;
+}
+
+.btn-remove:hover {
+    opacity: 1;
+}
+</style>
diff --git a/src/components/TagsManager.vue b/src/components/TagsManager.vue
new file mode 100644
index 000000000..4913eb091
--- /dev/null
+++ b/src/components/TagsManager.vue
@@ -0,0 +1,313 @@
+<template>
+    <div>
+        <h4 class="mb-3">{{ $t("Tags") }}</h4>
+        <div class="mb-3 p-1">
+            <tag
+                v-for="item in selectedTags"
+                :key="item.id"
+                :item="item"
+                :remove="deleteTag"
+            />
+        </div>
+        <div>
+            <vue-multiselect
+                v-model="newDraftTag.select"
+                class="mb-2"
+                :options="tagOptions"
+                :multiple="false"
+                :searchable="true"
+                :placeholder="$t('Add New below or Select...')"
+                track-by="id"
+                label="name"
+            >
+                <template #option="{ option }">
+                    <div class="mx-2 py-1 px-3 rounded d-inline-flex"
+                         style="margin-top: -5px; margin-bottom: -5px; height: 24px;"
+                         :style="{ color: textColor(option), backgroundColor: option.color + ' !important' }"
+                    >
+                        <span>
+                            {{ option.name }}</span>
+                    </div>
+                </template>
+                <template #singleLabel="{ option }">
+                    <div class="py-1 px-3 rounded d-inline-flex"
+                         style="height: 24px;"
+                         :style="{ color: textColor(option), backgroundColor: option.color + ' !important' }"
+                    >
+                        <span>{{ option.name }}</span>
+                    </div>
+                </template>
+            </vue-multiselect>
+            <div v-if="newDraftTag.select?.id == null" class="d-flex mb-2">
+                <div class="w-50 pe-2">
+                    <input v-model="newDraftTag.name" class="form-control" :class="{'is-invalid': newDraftTag.nameInvalid}" placeholder="name" />
+                    <div class="invalid-feedback">
+                        {{ $t("Tag with this name already exist.") }}
+                    </div>
+                </div>
+                <div class="w-50 ps-2">
+                    <vue-multiselect
+                        v-model="newDraftTag.color"
+                        :options="colorOptions"
+                        :multiple="false"
+                        :searchable="true"
+                        :placeholder="$t('color')"
+                        track-by="color"
+                        label="name"
+                        select-label=""
+                        deselect-label=""
+                    >
+                        <template #option="{ option }">
+                            <div class="mx-2 py-1 px-3 rounded d-inline-flex"
+                                 style="height: 24px; color: white;"
+                                 :style="{ backgroundColor: option.color + ' !important' }"
+                            >
+                                <span>{{ option.name }}</span>
+                            </div>
+                        </template>
+                        <template #singleLabel="{ option }">
+                            <div class="py-1 px-3 rounded d-inline-flex"
+                                 style="height: 24px; color: white;"
+                                 :style="{ backgroundColor: option.color + ' !important' }"
+                            >
+                                <span>{{ option.name }}</span>
+                            </div>
+                        </template>
+                    </vue-multiselect>
+                </div>
+            </div>
+            <input v-model="newDraftTag.value" class="form-control mb-2" :placeholder="$t('value (optional)')" />
+            <div class="mb-2">
+                <button
+                    type="button"
+                    class="btn btn-secondary float-end"
+                    :disabled="processing || newDraftTag.invalid"
+                    @click.stop="addDraftTag"
+                >
+                    {{ $t("Add") }}
+                </button>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import VueMultiselect from "vue-multiselect";
+import Tag from "../components/Tag.vue";
+import { useToast } from "vue-toastification"
+const toast = useToast()
+
+export default {
+    components: {
+        Tag,
+        VueMultiselect,
+    },
+    props: {
+        preSelectedTags: {
+            type: Array,
+            default: () => [],
+        },
+    },
+    data() {
+        return {
+            existingTags: [],
+            processing: false,
+            newTags: [],
+            deleteTags: [],
+            newDraftTag: {
+                name: null,
+                select: null,
+                color: null,
+                value: "",
+                invalid: true,
+                nameInvalid: false,
+            },
+        };
+    },
+    computed: {
+        tagOptions() {
+            return this.existingTags;
+        },
+        selectedTags() {
+            return this.preSelectedTags.concat(this.newTags).filter(tag => !this.deleteTags.find(monitorTag => monitorTag.id == tag.id));
+        },
+        colorOptions() {
+            return [
+                { name: this.$t("Gray"),
+                    color: "#4B5563" },
+                { name: this.$t("Red"),
+                    color: "#DC2626" },
+                { name: this.$t("Orange"),
+                    color: "#D97706" },
+                { name: this.$t("Green"),
+                    color: "#059669" },
+                { name: this.$t("Blue"),
+                    color: "#2563EB" },
+                { name: this.$t("Indigo"),
+                    color: "#4F46E5" },
+                { name: this.$t("Purple"),
+                    color: "#7C3AED" },
+                { name: this.$t("Pink"),
+                    color: "#DB2777" },
+            ]
+        }
+    },
+    watch: {
+        "newDraftTag.select": function (newSelected) {
+            this.newDraftTag.select = newSelected;
+            this.validateDraftTag();
+        },
+        "newDraftTag.name": function (newName) {
+            this.newDraftTag.name = newName.trim();
+            this.validateDraftTag();
+        },
+        "newDraftTag.color": function (newColor) {
+            this.newDraftTag.color = newColor;
+            this.validateDraftTag();
+        },
+    },
+    mounted() {
+        this.getExistingTags();
+    },
+    methods: {
+        getExistingTags() {
+            this.$root.getSocket().emit("getTags", (res) => {
+                if (res.ok) {
+                    this.existingTags = res.tags;
+                } else {
+                    toast.error(res.msg)
+                }
+            });
+        },
+        deleteTag(item) {
+            if (item.new) {
+                // Undo Adding a new Tag
+                this.newTags = this.newTags.filter(tag => tag.name != item.name && tag.value != item.value);
+            } else {
+                // Remove an Existing Tag
+                this.deleteTags.push(item);
+            }
+        },
+        validateDraftTag() {
+            if (this.newDraftTag.select != null) {
+                // Select an existing tag, no need to validate
+                this.newDraftTag.invalid = false;
+            } else if (this.existingTags.filter(tag => tag.name === this.newDraftTag.name).length > 0) {
+                // Try to create new tag with existing name
+                this.newDraftTag.nameInvalid = true;
+                this.newDraftTag.invalid = true;
+            } else if (this.newDraftTag.color == null || this.newDraftTag.name === "") {
+                // Missing form inputs
+                this.newDraftTag.nameInvalid = false;
+                this.newDraftTag.invalid = true;
+            } else {
+                // Looks valid
+                this.newDraftTag.invalid = false;
+                this.newDraftTag.nameInvalid = false;
+            }
+        },
+        textColor(option) {
+            if (option.color) {
+                return "white";
+            } else {
+                return this.$root.theme === "light" ? "var(--bs-body-color)" : "inherit";
+            }
+        },
+        addDraftTag() {
+            console.log("Adding Draft Tag: ", this.newDraftTag);
+            if (this.newDraftTag.select != null) {
+                // Add an existing Tag
+                this.newTags.push({
+                    id: this.newDraftTag.select.id,
+                    color: this.newDraftTag.select.color,
+                    name: this.newDraftTag.select.name,
+                    value: this.newDraftTag.value,
+                    new: true,
+                })
+            } else {
+                // Add new Tag
+                this.newTags.push({
+                    color: this.newDraftTag.color.color,
+                    name: this.newDraftTag.name,
+                    value: this.newDraftTag.value,
+                    new: true,
+                })
+            }
+        },
+        addTagAsync(newTag) {
+            return new Promise((resolve) => {
+                this.$root.getSocket().emit("addTag", newTag, resolve);
+            });
+        },
+        addMonitorTagAsync(tagId, monitorId, value) {
+            return new Promise((resolve) => {
+                this.$root.getSocket().emit("addMonitorTag", tagId, monitorId, value, resolve);
+            });
+        },
+        deleteMonitorTagAsync(tagId, monitorId) {
+            return new Promise((resolve) => {
+                this.$root.getSocket().emit("deleteMonitorTag", tagId, monitorId, resolve);
+            });
+        },
+        async submit(monitorId) {
+            console.log(`Submitting tag changes for monitor ${monitorId}...`);
+            this.processing = true;
+
+            for (const newTag of this.newTags) {
+                let tagId;
+                if (newTag.id == null) {
+                    let newTagResult;
+                    await this.addTagAsync(newTag).then((res) => {
+                        if (!res.ok) {
+                            toast.error(res.msg);
+                            newTagResult = false;
+                        }
+                        newTagResult = res.tag;
+                    });
+                    if (!newTagResult) {
+                        // abort
+                        this.processing = false;
+                        return;
+                    }
+                    tagId = newTagResult.id;
+                } else {
+                    tagId = newTag.id;
+                }
+
+                let newMonitorTagResult;
+                await this.addMonitorTagAsync(tagId, monitorId, newTag.value).then((res) => {
+                    if (!res.ok) {
+                        toast.error(res.msg);
+                        newMonitorTagResult = false;
+                    }
+                    newMonitorTagResult = true;
+                });
+                if (!newMonitorTagResult) {
+                    // abort
+                    this.processing = false;
+                    return;
+                }
+            }
+
+            for (const deleteTag of this.deleteTags) {
+                let deleteMonitorTagResult;
+                await this.deleteMonitorTagAsync(deleteTag.tag_id, deleteTag.monitor_id).then((res) => {
+                    if (!res.ok) {
+                        toast.error(res.msg);
+                        deleteMonitorTagResult = false;
+                    }
+                    deleteMonitorTagResult = true;
+                });
+                if (!deleteMonitorTagResult) {
+                    // abort
+                    this.processing = false;
+                    return;
+                }
+            }
+
+            this.getExistingTags();
+            this.processing = false;
+        }
+    },
+};
+</script>
diff --git a/src/icon.js b/src/icon.js
index 58583f0f8..56674f741 100644
--- a/src/icon.js
+++ b/src/icon.js
@@ -1,10 +1,37 @@
-import { library } from "@fortawesome/fontawesome-svg-core"
-import { faCog, faEdit, faPlus, faPause, faPlay, faTachometerAlt, faTrash, faList, faArrowAltCircleUp, faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons"
+import { library } from "@fortawesome/fontawesome-svg-core";
+import {
+    faArrowAltCircleUp,
+    faCog,
+    faEdit,
+    faEye,
+    faEyeSlash,
+    faList,
+    faPause,
+    faPlay,
+    faPlus,
+    faTachometerAlt,
+    faTimes,
+    faTrash
+} from "@fortawesome/free-solid-svg-icons";
 //import { fa } from '@fortawesome/free-regular-svg-icons'
-import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"
+import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
 
 // Add Free Font Awesome Icons here
 // https://fontawesome.com/v5.15/icons?d=gallery&p=2&s=solid&m=free
-library.add(faCog, faEdit, faPlus, faPause, faPlay, faTachometerAlt, faTrash, faList, faArrowAltCircleUp, faEye, faEyeSlash);
+library.add(
+    faArrowAltCircleUp,
+    faCog,
+    faEdit,
+    faEye,
+    faEyeSlash,
+    faList,
+    faPause,
+    faPlay,
+    faPlus,
+    faTachometerAlt,
+    faTimes,
+    faTrash,
+);
+
+export { FontAwesomeIcon };
 
-export { FontAwesomeIcon }
diff --git a/src/mixins/socket.js b/src/mixins/socket.js
index ea55f5a88..da6361486 100644
--- a/src/mixins/socket.js
+++ b/src/mixins/socket.js
@@ -266,6 +266,10 @@ export default {
             socket.emit("twoFAStatus", callback)
         },
 
+        getMonitorList(callback) {
+            socket.emit("getMonitorList", callback)
+        },
+
         add(monitor, callback) {
             socket.emit("add", monitor, callback)
         },
diff --git a/src/pages/Details.vue b/src/pages/Details.vue
index 9092b1792..c992d240b 100644
--- a/src/pages/Details.vue
+++ b/src/pages/Details.vue
@@ -2,6 +2,9 @@
     <transition name="slide-fade" appear>
         <div v-if="monitor">
             <h1> {{ monitor.name }}</h1>
+            <div class="tags">
+                <Tag v-for="tag in monitor.tags" :key="tag.id" :item="tag" :size="'sm'" />
+            </div>
             <p class="url">
                 <a v-if="monitor.type === 'http' || monitor.type === 'keyword' " :href="monitor.url" target="_blank">{{ monitor.url }}</a>
                 <span v-if="monitor.type === 'port'">TCP Ping {{ monitor.hostname }}:{{ monitor.port }}</span>
@@ -213,6 +216,7 @@ import CountUp from "../components/CountUp.vue";
 import Uptime from "../components/Uptime.vue";
 import Pagination from "v-pagination-3";
 const PingChart = defineAsyncComponent(() => import("../components/PingChart.vue"));
+import Tag from "../components/Tag.vue";
 
 export default {
     components: {
@@ -224,6 +228,7 @@ export default {
         Status,
         Pagination,
         PingChart,
+        Tag,
     },
     data() {
         return {
@@ -503,4 +508,12 @@ table {
     }
 }
 
+.tags {
+    margin-bottom: 0.5rem;
+}
+
+.tags > div:first-child {
+    margin-left: 0 !important;
+}
+
 </style>
diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue
index f98bb7560..d87bb4dd4 100644
--- a/src/pages/EditMonitor.vue
+++ b/src/pages/EditMonitor.vue
@@ -158,6 +158,10 @@
                                 </div>
                             </template>
 
+                            <div class="my-3">
+                                <tags-manager ref="tagsManager" :pre-selected-tags="monitor.tags"></tags-manager>
+                            </div>
+
                             <div class="mt-5 mb-1">
                                 <button class="btn btn-primary" type="submit" :disabled="processing">{{ $t("Save") }}</button>
                             </div>
@@ -197,6 +201,7 @@
 
 <script>
 import NotificationDialog from "../components/NotificationDialog.vue";
+import TagsManager from "../components/TagsManager.vue";
 import { useToast } from "vue-toastification"
 import VueMultiselect from "vue-multiselect"
 import { isDev } from "../util.ts";
@@ -205,6 +210,7 @@ const toast = useToast()
 export default {
     components: {
         NotificationDialog,
+        TagsManager,
         VueMultiselect,
     },
 
@@ -317,22 +323,28 @@ export default {
 
         },
 
-        submit() {
+        async submit() {
             this.processing = true;
 
             if (this.isAdd) {
-                this.$root.add(this.monitor, (res) => {
-                    this.processing = false;
+                this.$root.add(this.monitor, async (res) => {
 
                     if (res.ok) {
+                        await this.$refs.tagsManager.submit(res.monitorID);
+
                         toast.success(res.msg);
+                        this.processing = false;
+                        this.$root.getMonitorList();
                         this.$router.push("/dashboard/" + res.monitorID)
                     } else {
                         toast.error(res.msg);
+                        this.processing = false;
                     }
 
                 })
             } else {
+                await this.$refs.tagsManager.submit(this.monitor.id);
+
                 this.$root.getSocket().emit("editMonitor", this.monitor, (res) => {
                     this.processing = false;
                     this.$root.toastRes(res)
@@ -357,6 +369,8 @@ export default {
     .multiselect__tags {
         border-radius: 1.5rem;
         border: 1px solid #ced4da;
+        min-height: 38px;
+        padding: 6px 40px 0 8px;
     }
 
     .multiselect--active .multiselect__tags {
@@ -373,9 +387,25 @@ export default {
 
     .multiselect__tag {
         border-radius: 50rem;
+        margin-bottom: 0;
+        padding: 6px 26px 6px 10px;
         background: $primary !important;
     }
 
+    .multiselect__placeholder {
+        font-size: 1rem;
+        padding-left: 6px;
+        padding-top: 0;
+        padding-bottom: 0;
+        margin-bottom: 0;
+        opacity: 0.67;
+    }
+
+    .multiselect__input, .multiselect__single {
+        line-height: 14px;
+        margin-bottom: 0;
+    }
+
     .dark {
         .multiselect__tag {
             color: $dark-font-color2;