diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index 699733e37..8fcde4a6d 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -11,7 +11,7 @@ use Illuminate\Http\Request;
 
 class SearchController extends Controller
 {
-    protected $searchRunner;
+    protected SearchRunner $searchRunner;
 
     public function __construct(SearchRunner $searchRunner)
     {
diff --git a/resources/js/components/global-search.js b/resources/js/components/global-search.js
new file mode 100644
index 000000000..b351278d6
--- /dev/null
+++ b/resources/js/components/global-search.js
@@ -0,0 +1,47 @@
+/**
+ * @extends {Component}
+ */
+import {htmlToDom} from "../services/dom";
+
+class GlobalSearch {
+
+    setup() {
+        this.input = this.$refs.input;
+        this.suggestions = this.$refs.suggestions;
+        this.suggestionResultsWrap = this.$refs.suggestionResults;
+
+        this.setupListeners();
+    }
+
+    setupListeners() {
+        this.input.addEventListener('input', () => {
+            const value = this.input.value;
+            if (value.length > 0) {
+                this.updateSuggestions(value);
+            }  else {
+                this.hideSuggestions();
+            }
+        });
+    }
+
+    async updateSuggestions(search) {
+        const {data: results} = await window.$http.get('/ajax/search/entities', {term: search, count: 5});
+        const resultDom = htmlToDom(results);
+
+        const childrenToTrim = Array.from(resultDom.children).slice(9);
+        for (const child of childrenToTrim) {
+            child.remove();
+        }
+
+        this.suggestions.style.display = 'block';
+        this.suggestionResultsWrap.innerHTML = '';
+        this.suggestionResultsWrap.append(resultDom);
+    }
+
+    hideSuggestions() {
+        this.suggestions.style.display = null;
+        this.suggestionResultsWrap.innerHTML = '';
+    }
+}
+
+export default GlobalSearch;
\ No newline at end of file
diff --git a/resources/js/components/index.js b/resources/js/components/index.js
index 9f801668e..41dbf4de5 100644
--- a/resources/js/components/index.js
+++ b/resources/js/components/index.js
@@ -57,6 +57,7 @@ import triLayout from "./tri-layout.js"
 import userSelect from "./user-select.js"
 import webhookEvents from "./webhook-events";
 import wysiwygEditor from "./wysiwyg-editor.js"
+import globalSearch from "./global-search";
 
 const componentMapping = {
     "add-remove-rows": addRemoveRows,
@@ -86,6 +87,7 @@ const componentMapping = {
     "entity-selector-popup": entitySelectorPopup,
     "event-emit-select": eventEmitSelect,
     "expand-toggle": expandToggle,
+    "global-search": globalSearch,
     "header-mobile-toggle": headerMobileToggle,
     "homepage-control": homepageControl,
     "image-manager": imageManager,
diff --git a/resources/sass/_blocks.scss b/resources/sass/_blocks.scss
index 6058add82..302e7ed4e 100644
--- a/resources/sass/_blocks.scss
+++ b/resources/sass/_blocks.scss
@@ -86,11 +86,13 @@
 .card-title a {
   line-height: 1;
 }
-.card-footer-link {
+.card-footer-link, button.card-footer-link  {
   display: block;
   padding: $-s $-m;
   line-height: 1;
   border-top: 1px solid;
+  width: 100%;
+  text-align: left;
   @include lightDark(border-color, #DDD, #555);
   border-radius: 0 0 3px 3px;
   font-size: 0.9em;
diff --git a/resources/sass/_components.scss b/resources/sass/_components.scss
index 66d76aaa2..31ec6a2c0 100644
--- a/resources/sass/_components.scss
+++ b/resources/sass/_components.scss
@@ -1010,4 +1010,31 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
   border: 1px solid #b4b4b4;
   box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 2px 0 0 rgba(255, 255, 255, .7) inset;
   color: #333;
+}
+
+.global-search-suggestions {
+  display: none;
+  position: absolute;
+  top: -$-s;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  margin-left: -$-xxl;
+  margin-right: -$-xxl;
+  padding-top: 56px;
+  border-radius: 3px;
+  box-shadow: $bs-hover;
+  .entity-item-snippet p  {
+    display: none;
+  }
+  .entity-item-snippet {
+    font-size: .8rem;
+  }
+  .entity-list-item-name {
+    font-size: .9rem;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2;
+    overflow: hidden;
+  }
 }
\ No newline at end of file
diff --git a/resources/sass/_forms.scss b/resources/sass/_forms.scss
index 7de8a9d7d..709db3bd6 100644
--- a/resources/sass/_forms.scss
+++ b/resources/sass/_forms.scss
@@ -412,7 +412,7 @@ div[editor-type="markdown"] .title-input.page-title input[type="text"] {
 .search-box {
   max-width: 100%;
   position: relative;
-  button {
+  button[tabindex="-1"] {
     background-color: transparent;
     border: none;
     @include lightDark(color, #666, #AAA);
diff --git a/resources/sass/_header.scss b/resources/sass/_header.scss
index 923f026c2..e0b494e77 100644
--- a/resources/sass/_header.scss
+++ b/resources/sass/_header.scss
@@ -108,21 +108,6 @@ header .search-box {
       border: 1px solid rgba(255, 255, 255, 0.4);
     }
   }
-  button {
-    z-index: 1;
-    left: 16px;
-    top: 10px;
-    color: #FFF;
-    opacity: 0.6;
-    @include lightDark(color, rgba(255, 255, 255, 0.8), #AAA);
-    @include rtl {
-      left: auto;
-      right: 16px;
-    }
-    svg {
-      margin-block-end: 0;
-    }
-  }
   input::placeholder {
     color: #FFF;
     opacity: 0.6;
@@ -130,10 +115,25 @@ header .search-box {
   @include between($l, $xl) {
     max-width: 200px;
   }
-  &:focus-within button {
+  &:focus-within #header-search-box-button {
     opacity: 1;
   }
 }
+#header-search-box-button {
+  z-index: 1;
+  left: 16px;
+  top: 10px;
+  color: #FFF;
+  opacity: 0.6;
+  @include lightDark(color, rgba(255, 255, 255, 0.8), #AAA);
+  @include rtl {
+    left: auto;
+    right: 16px;
+  }
+  svg {
+    margin-block-end: 0;
+  }
+}
 
 .logo {
   display: inline-flex;
diff --git a/resources/views/common/header.blade.php b/resources/views/common/header.blade.php
index 9fe97b853..1340be26d 100644
--- a/resources/views/common/header.blade.php
+++ b/resources/views/common/header.blade.php
@@ -19,12 +19,19 @@
 
         <div class="flex-container-column items-center justify-center hide-under-l">
             @if (hasAppAccess())
-            <form action="{{ url('/search') }}" method="GET" class="search-box" role="search">
+            <form component="global-search" action="{{ url('/search') }}" method="GET" class="search-box" role="search">
                 <button id="header-search-box-button" type="submit" aria-label="{{ trans('common.search') }}" tabindex="-1">@icon('search') </button>
-                <input id="header-search-box-input" type="text" name="term"
+                <input id="header-search-box-input"
+                       refs="global-search@input"
+                       type="text"
+                       name="term"
                        data-shortcut="global_search"
                        aria-label="{{ trans('common.search') }}" placeholder="{{ trans('common.search') }}"
-                       value="{{ isset($searchTerm) ? $searchTerm : '' }}">
+                       value="{{ $searchTerm ?? '' }}">
+                <div refs="global-search@suggestions" class="global-search-suggestions card">
+                    <div refs="global-search@suggestion-results" class="px-m"></div>
+                    <button class="text-button card-footer-link" type="submit">{{ trans('common.view_all') }}</button>
+                </div>
             </form>
             @endif
         </div>