diff --git a/Gemfile.lock b/Gemfile.lock
index d0add73fd52aab149b9c546ceeed77a6c682fd02..3dc9764ccd1751df412e2e5fe300a7de1297e1e3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,15 +1,15 @@
-PATH
-  remote: vendor/gems/error_tracking_open_api
-  specs:
-    error_tracking_open_api (1.0.0)
-      typhoeus (~> 1.0, >= 1.0.1)
-
 PATH
   remote: vendor/gems/devise-pbkdf2-encryptable
   specs:
     devise-pbkdf2-encryptable (0.0.0)
       devise (~> 4.0)
 
+PATH
+  remote: vendor/gems/error_tracking_open_api
+  specs:
+    error_tracking_open_api (1.0.0)
+      typhoeus (~> 1.0, >= 1.0.1)
+
 PATH
   remote: vendor/gems/ipynbdiff
   specs:
diff --git a/app/assets/javascripts/header_search/components/app.vue b/app/assets/javascripts/header_search/components/app.vue
index adf304aebc76e403dabd51a09175bf0d634ca257..51f9ce9e00e3d672cb3b3c2aded5ee445110abb8 100644
--- a/app/assets/javascripts/header_search/components/app.vue
+++ b/app/assets/javascripts/header_search/components/app.vue
@@ -1,8 +1,15 @@
 <script>
-import { GlSearchBoxByType, GlOutsideDirective as Outside } from '@gitlab/ui';
+import {
+  GlSearchBoxByType,
+  GlOutsideDirective as Outside,
+  GlIcon,
+  GlToken,
+  GlResizeObserverDirective,
+} from '@gitlab/ui';
 import { mapState, mapActions, mapGetters } from 'vuex';
 import { debounce } from 'lodash';
 import { visitUrl } from '~/lib/utils/url_utility';
+import { truncate } from '~/lib/utils/text_utility';
 import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
 import { s__, sprintf } from '~/locale';
 import DropdownKeyboardNavigation from '~/vue_shared/components/dropdown_keyboard_navigation.vue';
@@ -12,6 +19,8 @@ import {
   SEARCH_INPUT_DESCRIPTION,
   SEARCH_RESULTS_DESCRIPTION,
   SEARCH_SHORTCUTS_MIN_CHARACTERS,
+  SCOPE_TOKEN_MAX_LENGTH,
+  INPUT_FIELD_PADDING,
 } from '../constants';
 import HeaderSearchAutocompleteItems from './header_search_autocomplete_items.vue';
 import HeaderSearchDefaultItems from './header_search_default_items.vue';
@@ -34,14 +43,17 @@ export default {
       'GlobalSearch|Results updated. %{count} results available. Use the up and down arrow keys to navigate search results list, or ENTER to submit.',
     ),
     searchResultsLoading: s__('GlobalSearch|Search results are loading'),
+    searchResultsScope: s__('GlobalSearch|in %{scope}'),
   },
-  directives: { Outside },
+  directives: { Outside, GlResizeObserverDirective },
   components: {
     GlSearchBoxByType,
     HeaderSearchDefaultItems,
     HeaderSearchScopedItems,
     HeaderSearchAutocompleteItems,
     DropdownKeyboardNavigation,
+    GlIcon,
+    GlToken,
   },
   data() {
     return {
@@ -50,8 +62,8 @@ export default {
     };
   },
   computed: {
-    ...mapState(['search', 'loading']),
-    ...mapGetters(['searchQuery', 'searchOptions', 'autocompleteGroupedSearchOptions']),
+    ...mapState(['search', 'loading', 'searchContext']),
+    ...mapGetters(['searchQuery', 'searchOptions']),
     searchText: {
       get() {
         return this.search;
@@ -70,16 +82,17 @@ export default {
       return Boolean(gon?.current_username);
     },
     showSearchDropdown() {
-      const hasResultsUnderMinCharacters =
-        this.searchText?.length === 1 ? this?.autocompleteGroupedSearchOptions?.length > 0 : true;
+      if (!this.showDropdown || !this.isLoggedIn) {
+        return false;
+      }
 
-      return this.showDropdown && this.isLoggedIn && hasResultsUnderMinCharacters;
+      return this.searchOptions?.length > 0;
     },
     showDefaultItems() {
       return !this.searchText;
     },
-    showShortcuts() {
-      return this.searchText && this.searchText?.length >= SEARCH_SHORTCUTS_MIN_CHARACTERS;
+    showScopes() {
+      return this.searchText?.length > SEARCH_SHORTCUTS_MIN_CHARACTERS;
     },
     defaultIndex() {
       if (this.showDefaultItems) {
@@ -88,11 +101,11 @@ export default {
 
       return FIRST_DROPDOWN_INDEX;
     },
+
     searchInputDescribeBy() {
       if (this.isLoggedIn) {
         return this.$options.i18n.searchInputDescribeByWithDropdown;
       }
-
       return this.$options.i18n.searchInputDescribeByNoDropdown;
     },
     dropdownResultsDescription() {
@@ -112,8 +125,26 @@ export default {
             count: this.searchOptions.length,
           });
     },
-    headerSearchActivityDescriptor() {
-      return this.showDropdown ? 'is-active' : 'is-not-active';
+    searchBarStateIndicator() {
+      const hasIcon =
+        this.searchContext?.project || this.searchContext?.group ? 'has-icon' : 'has-no-icon';
+      const isSearching = this.showScopes ? 'is-searching' : 'is-not-searching';
+      const isActive = this.showSearchDropdown ? 'is-active' : 'is-not-active';
+      return `${isActive} ${isSearching} ${hasIcon}`;
+    },
+    searchBarItem() {
+      return this.searchOptions?.[0];
+    },
+    infieldHelpContent() {
+      return this.searchBarItem?.scope || this.searchBarItem?.description;
+    },
+    infieldHelpIcon() {
+      return this.searchBarItem?.icon;
+    },
+    scopeTokenTitle() {
+      return sprintf(this.$options.i18n.searchResultsScope, {
+        scope: this.infieldHelpContent,
+      });
     },
   },
   methods: {
@@ -127,6 +158,9 @@ export default {
       this.$emit('toggleDropdown', this.showDropdown);
     },
     submitSearch() {
+      if (this.search?.length <= SEARCH_SHORTCUTS_MIN_CHARACTERS && this.currentFocusIndex < 0) {
+        return null;
+      }
       return visitUrl(this.currentFocusedOption?.url || this.searchQuery);
     },
     getAutocompleteOptions: debounce(function debouncedSearch(searchTerm) {
@@ -136,8 +170,19 @@ export default {
         this.fetchAutocompleteOptions();
       }
     }, DEFAULT_DEBOUNCE_AND_THROTTLE_MS),
+    getTruncatedScope(scope) {
+      return truncate(scope, SCOPE_TOKEN_MAX_LENGTH);
+    },
+    observeTokenWidth({ contentRect: { width } }) {
+      const inputField = this.$refs?.searchInputBox?.$el?.querySelector('input');
+      if (!inputField) {
+        return;
+      }
+      inputField.style.paddingRight = `${width + INPUT_FIELD_PADDING}px`;
+    },
   },
   SEARCH_BOX_INDEX,
+  FIRST_DROPDOWN_INDEX,
   SEARCH_INPUT_DESCRIPTION,
   SEARCH_RESULTS_DESCRIPTION,
 };
@@ -149,10 +194,12 @@ export default {
     role="search"
     :aria-label="$options.i18n.searchGitlab"
     class="header-search gl-relative gl-rounded-base gl-w-full"
-    :class="headerSearchActivityDescriptor"
+    :class="searchBarStateIndicator"
+    data-testid="header-search-form"
   >
     <gl-search-box-by-type
       id="search"
+      ref="searchInputBox"
       v-model="searchText"
       role="searchbox"
       class="gl-z-index-1"
@@ -165,7 +212,28 @@ export default {
       @click="openDropdown"
       @input="getAutocompleteOptions"
       @keydown.enter.stop.prevent="submitSearch"
+      @keydown.esc.stop.prevent="closeDropdown"
     />
+    <gl-token
+      v-if="showScopes"
+      v-gl-resize-observer-directive="observeTokenWidth"
+      class="in-search-scope-help"
+      :view-only="true"
+      :title="scopeTokenTitle"
+      ><gl-icon
+        v-if="infieldHelpIcon"
+        class="gl-mr-2"
+        :aria-label="infieldHelpContent"
+        :name="infieldHelpIcon"
+        :size="16"
+      />{{
+        getTruncatedScope(
+          sprintf($options.i18n.searchResultsScope, {
+            scope: infieldHelpContent,
+          }),
+        )
+      }}
+    </gl-token>
     <span :id="$options.SEARCH_INPUT_DESCRIPTION" role="region" class="gl-sr-only">{{
       searchInputDescribeBy
     }}</span>
@@ -187,7 +255,7 @@ export default {
         <dropdown-keyboard-navigation
           v-model="currentFocusIndex"
           :max="searchOptions.length - 1"
-          :min="$options.SEARCH_BOX_INDEX"
+          :min="$options.FIRST_DROPDOWN_INDEX"
           :default-index="defaultIndex"
           @tab="closeDropdown"
         />
@@ -197,7 +265,7 @@ export default {
         />
         <template v-else>
           <header-search-scoped-items
-            v-if="showShortcuts"
+            v-if="showScopes"
             :current-focused-option="currentFocusedOption"
           />
           <header-search-autocomplete-items :current-focused-option="currentFocusedOption" />
diff --git a/app/assets/javascripts/header_search/components/header_search_scoped_items.vue b/app/assets/javascripts/header_search/components/header_search_scoped_items.vue
index 34d1bd713997480638c3707aac63d12430224ca8..f5be1bcb78676d5bc21af2f183af23ef49dfb437 100644
--- a/app/assets/javascripts/header_search/components/header_search_scoped_items.vue
+++ b/app/assets/javascripts/header_search/components/header_search_scoped_items.vue
@@ -1,13 +1,16 @@
 <script>
-import { GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
+import { GlDropdownItem, GlIcon, GlToken } from '@gitlab/ui';
 import { mapState, mapGetters } from 'vuex';
-import { __, sprintf } from '~/locale';
+import { s__, sprintf } from '~/locale';
+import { truncate } from '~/lib/utils/text_utility';
+import { SCOPE_TOKEN_MAX_LENGTH } from '../constants';
 
 export default {
   name: 'HeaderSearchScopedItems',
   components: {
     GlDropdownItem,
-    GlDropdownDivider,
+    GlIcon,
+    GlToken,
   },
   props: {
     currentFocusedOption: {
@@ -25,12 +28,21 @@ export default {
       return this.currentFocusedOption?.html_id === option.html_id;
     },
     ariaLabel(option) {
-      return sprintf(__('%{search} %{description} %{scope}'), {
+      return sprintf(s__('GlobalSearch| %{search} %{description} %{scope}'), {
         search: this.search,
-        description: option.description,
+        description: option.description || option.icon,
         scope: option.scope || '',
       });
     },
+    titleLabel(option) {
+      return sprintf(s__('GlobalSearch|in %{scope}'), {
+        search: this.search,
+        scope: option.scope || option.description,
+      });
+    },
+    getTruncatedScope(scope) {
+      return truncate(scope, SCOPE_TOKEN_MAX_LENGTH);
+    },
   },
 };
 </script>
@@ -42,18 +54,30 @@ export default {
       :id="option.html_id"
       :ref="option.html_id"
       :key="option.html_id"
+      class="gl-max-w-full"
       :class="{ 'gl-bg-gray-50': isOptionFocused(option) }"
       :aria-selected="isOptionFocused(option)"
       :aria-label="ariaLabel(option)"
       tabindex="-1"
       :href="option.url"
+      :title="titleLabel(option)"
     >
-      <span aria-hidden="true">
-        "<span class="gl-font-weight-bold">{{ search }}</span
-        >" {{ option.description }}
-        <span v-if="option.scope" class="gl-font-style-italic">{{ option.scope }}</span>
+      <span
+        ref="token-text-content"
+        class="gl-display-flex gl-justify-content-start search-text-content gl-line-height-24 gl-align-items-start gl-flex-direction-row gl-w-full"
+      >
+        <gl-icon name="search" class="gl-flex-shrink-0 gl-mr-2 gl-relative gl-pt-2" />
+        <span class="gl-flex-grow-1 gl-relative">
+          <gl-token
+            class="in-dropdown-scope-help has-icon gl-flex-shrink-0 gl-relative gl-white-space-nowrap gl-float-right gl-mr-n3!"
+            :view-only="true"
+          >
+            <gl-icon v-if="option.icon" :name="option.icon" class="gl-mr-2" />
+            <span>{{ getTruncatedScope(titleLabel(option)) }}</span>
+          </gl-token>
+          {{ search }}
+        </span>
       </span>
     </gl-dropdown-item>
-    <gl-dropdown-divider v-if="autocompleteGroupedSearchOptions.length > 0" />
   </div>
 </template>
diff --git a/app/assets/javascripts/header_search/constants.js b/app/assets/javascripts/header_search/constants.js
index 045a552efb070e8c70993b46f979726c0fa38e47..c9b05c3deb5aa9a55b46aedceb71636a6245a270 100644
--- a/app/assets/javascripts/header_search/constants.js
+++ b/app/assets/javascripts/header_search/constants.js
@@ -10,15 +10,21 @@ export const MSG_MR_IM_REVIEWER = s__("GlobalSearch|Merge requests that I'm a re
 
 export const MSG_MR_IVE_CREATED = s__("GlobalSearch|Merge requests I've created");
 
-export const MSG_IN_ALL_GITLAB = s__('GlobalSearch|in all GitLab');
+export const MSG_IN_ALL_GITLAB = s__('GlobalSearch|all GitLab');
 
-export const MSG_IN_GROUP = s__('GlobalSearch|in group');
+export const MSG_IN_GROUP = s__('GlobalSearch|group');
 
-export const MSG_IN_PROJECT = s__('GlobalSearch|in project');
+export const MSG_IN_PROJECT = s__('GlobalSearch|project');
 
-export const GROUPS_CATEGORY = 'Groups';
+export const ICON_PROJECT = 'project';
 
-export const PROJECTS_CATEGORY = 'Projects';
+export const ICON_GROUP = 'group';
+
+export const ICON_SUBGROUP = 'subgroup';
+
+export const GROUPS_CATEGORY = s__('GlobalSearch|Groups');
+
+export const PROJECTS_CATEGORY = s__('GlobalSearch|Projects');
 
 export const ISSUES_CATEGORY = 'Recent issues';
 
@@ -39,3 +45,7 @@ export const SEARCH_SHORTCUTS_MIN_CHARACTERS = 2;
 export const SEARCH_INPUT_DESCRIPTION = 'search-input-description';
 
 export const SEARCH_RESULTS_DESCRIPTION = 'search-results-description';
+
+export const SCOPE_TOKEN_MAX_LENGTH = 36;
+
+export const INPUT_FIELD_PADDING = 52;
diff --git a/app/assets/javascripts/header_search/store/getters.js b/app/assets/javascripts/header_search/store/getters.js
index 7d08aa859fb9560f4183e656e8c2611f07767d62..da7bccd35c048f9bd47543d73a3dfa8214a7291f 100644
--- a/app/assets/javascripts/header_search/store/getters.js
+++ b/app/assets/javascripts/header_search/store/getters.js
@@ -7,9 +7,13 @@ import {
   MSG_MR_ASSIGNED_TO_ME,
   MSG_MR_IM_REVIEWER,
   MSG_MR_IVE_CREATED,
-  MSG_IN_PROJECT,
-  MSG_IN_GROUP,
+  ICON_GROUP,
+  ICON_SUBGROUP,
+  ICON_PROJECT,
   MSG_IN_ALL_GITLAB,
+  PROJECTS_CATEGORY,
+  GROUPS_CATEGORY,
+  SEARCH_SHORTCUTS_MIN_CHARACTERS,
 } from '../constants';
 
 export const searchQuery = (state) => {
@@ -149,7 +153,8 @@ export const scopedSearchOptions = (state, getters) => {
     options.push({
       html_id: 'scoped-in-project',
       scope: state.searchContext.project?.name || '',
-      description: MSG_IN_PROJECT,
+      scopeCategory: PROJECTS_CATEGORY,
+      icon: ICON_PROJECT,
       url: getters.projectUrl,
     });
   }
@@ -158,7 +163,8 @@ export const scopedSearchOptions = (state, getters) => {
     options.push({
       html_id: 'scoped-in-group',
       scope: state.searchContext.group?.name || '',
-      description: MSG_IN_GROUP,
+      scopeCategory: GROUPS_CATEGORY,
+      icon: state.searchContext.group?.full_name?.includes('/') ? ICON_SUBGROUP : ICON_GROUP,
       url: getters.groupUrl,
     });
   }
@@ -190,6 +196,7 @@ export const autocompleteGroupedSearchOptions = (state) => {
       results.push(groupedOptions[option.category]);
     }
   });
+
   return results;
 };
 
@@ -205,5 +212,9 @@ export const searchOptions = (state, getters) => {
     [],
   );
 
+  if (state.search?.length <= SEARCH_SHORTCUTS_MIN_CHARACTERS) {
+    return sortedAutocompleteOptions;
+  }
+
   return getters.scopedSearchOptions.concat(sortedAutocompleteOptions);
 };
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 8755db83d35a83216117451167a0825dfa0c90d3..e23c797156a4ae59800624dc721d81ba795943e3 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -4,7 +4,8 @@ $search-sidebar-min-width: 240px;
 $search-sidebar-max-width: 300px;
 $search-input-field-x-min-width: 200px;
 $search-input-field-min-width: 320px;
-$search-input-field-max-width: 600px;
+$search-input-field-max-width: 640px;
+$search-keyboard-shortcut: '/';
 
 $border-radius-medium: 3px;
 
@@ -67,54 +68,58 @@ input[type='checkbox']:hover {
   }
 }
 
-// This is a temporary workaround!
-// the button in GitLab UI Search components need to be updated to not be the small size
-// see in Figma: https://www.figma.com/file/qEddyqCrI7kPSBjGmwkZzQ/Component-library?node-id=43905%3A45540
-.header-search .gl-search-box-by-type-clear.btn-sm {
-  padding: 0.5rem !important;
-}
-
 .header-search {
   min-width: $search-input-field-min-width;
 
+  // This is a temporary workaround!
+  // the button in GitLab UI Search components need to be updated to not be the small size
+  // see in Figma: https://www.figma.com/file/qEddyqCrI7kPSBjGmwkZzQ/Component-library?node-id=43905%3A45540
+  .gl-search-box-by-type-clear.btn-sm {
+    padding: 0.5rem !important;
+  }
+
   @include media-breakpoint-between(md, lg) {
     min-width: $search-input-field-x-min-width;
   }
 
-  input,
-  svg {
-    transition: border-color ease-in-out $default-transition-duration,
-      background-color ease-in-out $default-transition-duration;
+  &.is-active {
+    &.is-searching {
+      .in-search-scope-help {
+        position: absolute;
+        top: $gl-spacing-scale-2;
+        right: 2.125rem;
+        z-index: 2;
+      }
+    }
+  }
+
+  &.is-not-searching {
+    .in-search-scope-help {
+      display: none;
+    }
   }
 
   &.is-not-active {
-    .btn.gl-clear-icon-button {
+    .btn.gl-clear-icon-button,
+    .in-search-scope-help {
       display: none;
     }
 
     &::after {
-      content: '/';
-      display: inline-block;
+      content: $search-keyboard-shortcut;
+      transform: translateY(calc(50% - #{$gl-spacing-scale-2}));
       position: absolute;
       top: 0;
-      right: 8px;
-      transform: translateY(calc(50% - 4px));
-      padding: 4px 5px;
+      right: $gl-spacing-scale-3;
+      padding: $gl-spacing-scale-2 5px;
       font-size: $gl-font-size-small;
       font-family: $monospace-font;
       line-height: 1;
       vertical-align: middle;
       border-width: 0;
-      border-style: solid;
-      border-image: none;
       border-radius: $border-radius-medium;
       box-shadow: none;
-      white-space: pre-wrap;
       box-sizing: border-box;
-      // Safari
-      word-wrap: break-word;
-      overflow-wrap: break-word;
-      word-break: keep-all;
     }
   }
 }
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index 4cefa60b12a1aac7b41ea598bb5e6f6a951ecdf8..1dcc34b213f3b738313316a47e674c0d59021c38 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -1504,7 +1504,7 @@ svg.s16 {
   vertical-align: -3px;
 }
 .header-content .header-search-new {
-  max-width: 600px;
+  max-width: 640px;
 }
 .header-search {
   min-width: 320px;
@@ -1516,27 +1516,20 @@ svg.s16 {
 }
 .header-search.is-not-active::after {
   content: "/";
-  display: inline-block;
+  transform: translateY(calc(50% - 0.25rem));
   position: absolute;
   top: 0;
-  right: 8px;
-  transform: translateY(calc(50% - 4px));
-  padding: 4px 5px;
+  right: 0.5rem;
+  padding: 0.25rem 5px;
   font-size: 12px;
   font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas",
     "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
   line-height: 1;
   vertical-align: middle;
   border-width: 0;
-  border-style: solid;
-  border-image: none;
   border-radius: 3px;
   box-shadow: none;
-  white-space: pre-wrap;
   box-sizing: border-box;
-  word-wrap: break-word;
-  overflow-wrap: break-word;
-  word-break: keep-all;
 }
 .search {
   margin: 0 8px;
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index cb3c97f18a30051ecc4f7e451a0217ae2d6ae036..ea7323cae904050741b619b4e6fa5f4d3420ab08 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -1489,7 +1489,7 @@ svg.s16 {
   vertical-align: -3px;
 }
 .header-content .header-search-new {
-  max-width: 600px;
+  max-width: 640px;
 }
 .header-search {
   min-width: 320px;
@@ -1501,27 +1501,20 @@ svg.s16 {
 }
 .header-search.is-not-active::after {
   content: "/";
-  display: inline-block;
+  transform: translateY(calc(50% - 0.25rem));
   position: absolute;
   top: 0;
-  right: 8px;
-  transform: translateY(calc(50% - 4px));
-  padding: 4px 5px;
+  right: 0.5rem;
+  padding: 0.25rem 5px;
   font-size: 12px;
   font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas",
     "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
   line-height: 1;
   vertical-align: middle;
   border-width: 0;
-  border-style: solid;
-  border-image: none;
   border-radius: 3px;
   box-shadow: none;
-  white-space: pre-wrap;
   box-sizing: border-box;
-  word-wrap: break-word;
-  overflow-wrap: break-word;
-  word-break: keep-all;
 }
 .search {
   margin: 0 8px;
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 126d2e0f82999f81c672ed572f9ca9b2db084629..ecbcaec27bcf0f5f22de8cd1603689cc972909a6 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -170,7 +170,7 @@ def search_sort_options
   # search_context exposes a bit too much data to the frontend, this controls what data we share and when.
   def header_search_context
     {}.tap do |hash|
-      hash[:group] = { id: search_context.group.id, name: search_context.group.name } if search_context.for_group?
+      hash[:group] = { id: search_context.group.id, name: search_context.group.name, full_name: search_context.group.full_name } if search_context.for_group?
       hash[:group_metadata] = search_context.group_metadata if search_context.for_group?
 
       hash[:project] = { id: search_context.project.id, name: search_context.project.name } if search_context.for_project?
diff --git a/ee/app/assets/stylesheets/startup/startup-dark.scss b/ee/app/assets/stylesheets/startup/startup-dark.scss
index 4cefa60b12a1aac7b41ea598bb5e6f6a951ecdf8..1dcc34b213f3b738313316a47e674c0d59021c38 100644
--- a/ee/app/assets/stylesheets/startup/startup-dark.scss
+++ b/ee/app/assets/stylesheets/startup/startup-dark.scss
@@ -1504,7 +1504,7 @@ svg.s16 {
   vertical-align: -3px;
 }
 .header-content .header-search-new {
-  max-width: 600px;
+  max-width: 640px;
 }
 .header-search {
   min-width: 320px;
@@ -1516,27 +1516,20 @@ svg.s16 {
 }
 .header-search.is-not-active::after {
   content: "/";
-  display: inline-block;
+  transform: translateY(calc(50% - 0.25rem));
   position: absolute;
   top: 0;
-  right: 8px;
-  transform: translateY(calc(50% - 4px));
-  padding: 4px 5px;
+  right: 0.5rem;
+  padding: 0.25rem 5px;
   font-size: 12px;
   font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas",
     "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
   line-height: 1;
   vertical-align: middle;
   border-width: 0;
-  border-style: solid;
-  border-image: none;
   border-radius: 3px;
   box-shadow: none;
-  white-space: pre-wrap;
   box-sizing: border-box;
-  word-wrap: break-word;
-  overflow-wrap: break-word;
-  word-break: keep-all;
 }
 .search {
   margin: 0 8px;
diff --git a/ee/app/assets/stylesheets/startup/startup-general.scss b/ee/app/assets/stylesheets/startup/startup-general.scss
index cb3c97f18a30051ecc4f7e451a0217ae2d6ae036..ea7323cae904050741b619b4e6fa5f4d3420ab08 100644
--- a/ee/app/assets/stylesheets/startup/startup-general.scss
+++ b/ee/app/assets/stylesheets/startup/startup-general.scss
@@ -1489,7 +1489,7 @@ svg.s16 {
   vertical-align: -3px;
 }
 .header-content .header-search-new {
-  max-width: 600px;
+  max-width: 640px;
 }
 .header-search {
   min-width: 320px;
@@ -1501,27 +1501,20 @@ svg.s16 {
 }
 .header-search.is-not-active::after {
   content: "/";
-  display: inline-block;
+  transform: translateY(calc(50% - 0.25rem));
   position: absolute;
   top: 0;
-  right: 8px;
-  transform: translateY(calc(50% - 4px));
-  padding: 4px 5px;
+  right: 0.5rem;
+  padding: 0.25rem 5px;
   font-size: 12px;
   font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas",
     "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
   line-height: 1;
   vertical-align: middle;
   border-width: 0;
-  border-style: solid;
-  border-image: none;
   border-radius: 3px;
   box-shadow: none;
-  white-space: pre-wrap;
   box-sizing: border-box;
-  word-wrap: break-word;
-  overflow-wrap: break-word;
-  word-break: keep-all;
 }
 .search {
   margin: 0 8px;
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 61b600d52a4d410561dbcaefc7b5476fa6e1d34d..b132952c92495a0fc2e90015660cb71a4fbdfa82 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -938,9 +938,6 @@ msgstr ""
 msgid "%{scope} results for term '%{term}'"
 msgstr ""
 
-msgid "%{search} %{description} %{scope}"
-msgstr ""
-
 msgid "%{seconds}s"
 msgstr ""
 
@@ -17690,9 +17687,15 @@ msgstr ""
 msgid "Global notification settings"
 msgstr ""
 
+msgid "GlobalSearch| %{search} %{description} %{scope}"
+msgstr ""
+
 msgid "GlobalSearch|%{count} default results provided. Use the up and down arrow keys to navigate search results list."
 msgstr ""
 
+msgid "GlobalSearch|Groups"
+msgstr ""
+
 msgid "GlobalSearch|Issues I've created"
 msgstr ""
 
@@ -17708,6 +17711,9 @@ msgstr ""
 msgid "GlobalSearch|Merge requests that I'm a reviewer"
 msgstr ""
 
+msgid "GlobalSearch|Projects"
+msgstr ""
+
 msgid "GlobalSearch|Results updated. %{count} results available. Use the up and down arrow keys to navigate search results list, or ENTER to submit."
 msgstr ""
 
@@ -17732,13 +17738,16 @@ msgstr ""
 msgid "GlobalSearch|What are you searching for?"
 msgstr ""
 
-msgid "GlobalSearch|in all GitLab"
+msgid "GlobalSearch|all GitLab"
+msgstr ""
+
+msgid "GlobalSearch|group"
 msgstr ""
 
-msgid "GlobalSearch|in group"
+msgid "GlobalSearch|in %{scope}"
 msgstr ""
 
-msgid "GlobalSearch|in project"
+msgid "GlobalSearch|project"
 msgstr ""
 
 msgid "Globally-allowed IP ranges"
diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb
index 7350a54e8df5963e8a2784ee362cfaead7dc4f57..1523586ab26feb601c130f3b511f825aedd1b884 100644
--- a/spec/features/search/user_uses_header_search_field_spec.rb
+++ b/spec/features/search/user_uses_header_search_field_spec.rb
@@ -153,6 +153,7 @@
 
       it 'displays search options' do
         fill_in_search('test')
+
         expect(page).to have_selector(scoped_search_link('test', search_code: true))
         expect(page).to have_selector(scoped_search_link('test', group_id: group.id, search_code: true))
         expect(page).to have_selector(scoped_search_link('test', project_id: project.id, group_id: group.id, search_code: true))
@@ -167,6 +168,7 @@
 
       it 'displays search options' do
         fill_in_search('test')
+        sleep 0.5
         expect(page).to have_selector(scoped_search_link('test', search_code: true, repository_ref: 'master'))
         expect(page).not_to have_selector(scoped_search_link('test', search_code: true, group_id: project.namespace_id, repository_ref: 'master'))
         expect(page).to have_selector(scoped_search_link('test', search_code: true, project_id: project.id, repository_ref: 'master'))
@@ -184,7 +186,7 @@
         fill_in_search('Feature')
 
         within(dashboard_search_options_popup_menu) do
-          expect(page).to have_text('"Feature" in all GitLab')
+          expect(page).to have_text('Feature in all GitLab')
           expect(page).to have_no_text('Feature Flags')
         end
       end
diff --git a/spec/frontend/header_search/components/app_spec.js b/spec/frontend/header_search/components/app_spec.js
index f0de5b083ae476a7da91658befda6ef2619dc14c..5f2b71a22c5c6a5c07bf01c11efc22a070fa9b95 100644
--- a/spec/frontend/header_search/components/app_spec.js
+++ b/spec/frontend/header_search/components/app_spec.js
@@ -1,22 +1,32 @@
-import { GlSearchBoxByType } from '@gitlab/ui';
+import { GlSearchBoxByType, GlToken, GlIcon } from '@gitlab/ui';
 import Vue, { nextTick } from 'vue';
 import Vuex from 'vuex';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { s__, sprintf } from '~/locale';
 import HeaderSearchApp from '~/header_search/components/app.vue';
 import HeaderSearchAutocompleteItems from '~/header_search/components/header_search_autocomplete_items.vue';
 import HeaderSearchDefaultItems from '~/header_search/components/header_search_default_items.vue';
 import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue';
-import { SEARCH_INPUT_DESCRIPTION, SEARCH_RESULTS_DESCRIPTION } from '~/header_search/constants';
+import {
+  SEARCH_INPUT_DESCRIPTION,
+  SEARCH_RESULTS_DESCRIPTION,
+  SEARCH_BOX_INDEX,
+  ICON_PROJECT,
+  ICON_GROUP,
+  ICON_SUBGROUP,
+  SCOPE_TOKEN_MAX_LENGTH,
+} from '~/header_search/constants';
 import DropdownKeyboardNavigation from '~/vue_shared/components/dropdown_keyboard_navigation.vue';
 import { ENTER_KEY } from '~/lib/utils/keys';
 import { visitUrl } from '~/lib/utils/url_utility';
+import { truncate } from '~/lib/utils/text_utility';
 import {
   MOCK_SEARCH,
   MOCK_SEARCH_QUERY,
   MOCK_USERNAME,
   MOCK_DEFAULT_SEARCH_OPTIONS,
   MOCK_SCOPED_SEARCH_OPTIONS,
-  MOCK_SORTED_AUTOCOMPLETE_OPTIONS,
+  MOCK_SEARCH_CONTEXT_FULL,
 } from '../mock_data';
 
 Vue.use(Vuex);
@@ -52,11 +62,26 @@ describe('HeaderSearchApp', () => {
     });
   };
 
+  const formatScopeName = (scopeName) => {
+    if (!scopeName) {
+      return false;
+    }
+    const searchResultsScope = s__('GlobalSearch|in %{scope}');
+    return truncate(
+      sprintf(searchResultsScope, {
+        scope: scopeName,
+      }),
+      SCOPE_TOKEN_MAX_LENGTH,
+    );
+  };
+
   afterEach(() => {
     wrapper.destroy();
   });
 
+  const findHeaderSearchForm = () => wrapper.findByTestId('header-search-form');
   const findHeaderSearchInput = () => wrapper.findComponent(GlSearchBoxByType);
+  const findScopeToken = () => wrapper.findComponent(GlToken);
   const findHeaderSearchDropdown = () => wrapper.findByTestId('header-search-dropdown-menu');
   const findHeaderSearchDefaultItems = () => wrapper.findComponent(HeaderSearchDefaultItems);
   const findHeaderSearchScopedItems = () => wrapper.findComponent(HeaderSearchScopedItems);
@@ -106,53 +131,38 @@ describe('HeaderSearchApp', () => {
     });
 
     describe.each`
-      search         | showDefault | showScoped | showAutocomplete | showDropdownNavigation
-      ${null}        | ${true}     | ${false}   | ${false}         | ${true}
-      ${''}          | ${true}     | ${false}   | ${false}         | ${true}
-      ${'1'}         | ${false}    | ${false}   | ${false}         | ${false}
-      ${')'}         | ${false}    | ${false}   | ${false}         | ${false}
-      ${'t'}         | ${false}    | ${false}   | ${true}          | ${true}
-      ${'te'}        | ${false}    | ${true}    | ${true}          | ${true}
-      ${'tes'}       | ${false}    | ${true}    | ${true}          | ${true}
-      ${MOCK_SEARCH} | ${false}    | ${true}    | ${true}          | ${true}
-    `(
-      'Header Search Dropdown Items',
-      ({ search, showDefault, showScoped, showAutocomplete, showDropdownNavigation }) => {
-        describe(`when search is ${search}`, () => {
-          beforeEach(() => {
-            window.gon.current_username = MOCK_USERNAME;
-            createComponent(
-              { search },
-              {
-                autocompleteGroupedSearchOptions: () =>
-                  search.match(/^[A-Za-z]+$/g) ? MOCK_SORTED_AUTOCOMPLETE_OPTIONS : [],
-              },
-            );
-            findHeaderSearchInput().vm.$emit('click');
-          });
+      search         | showDefault | showScoped | showAutocomplete
+      ${null}        | ${true}     | ${false}   | ${false}
+      ${''}          | ${true}     | ${false}   | ${false}
+      ${'t'}         | ${false}    | ${false}   | ${true}
+      ${'te'}        | ${false}    | ${false}   | ${true}
+      ${'tes'}       | ${false}    | ${true}    | ${true}
+      ${MOCK_SEARCH} | ${false}    | ${true}    | ${true}
+    `('Header Search Dropdown Items', ({ search, showDefault, showScoped, showAutocomplete }) => {
+      describe(`when search is ${search}`, () => {
+        beforeEach(() => {
+          window.gon.current_username = MOCK_USERNAME;
+          createComponent({ search }, {});
+          findHeaderSearchInput().vm.$emit('click');
+        });
 
-          it(`should${showDefault ? '' : ' not'} render the Default Dropdown Items`, () => {
-            expect(findHeaderSearchDefaultItems().exists()).toBe(showDefault);
-          });
+        it(`should${showDefault ? '' : ' not'} render the Default Dropdown Items`, () => {
+          expect(findHeaderSearchDefaultItems().exists()).toBe(showDefault);
+        });
 
-          it(`should${showScoped ? '' : ' not'} render the Scoped Dropdown Items`, () => {
-            expect(findHeaderSearchScopedItems().exists()).toBe(showScoped);
-          });
+        it(`should${showScoped ? '' : ' not'} render the Scoped Dropdown Items`, () => {
+          expect(findHeaderSearchScopedItems().exists()).toBe(showScoped);
+        });
 
-          it(`should${
-            showAutocomplete ? '' : ' not'
-          } render the Autocomplete Dropdown Items`, () => {
-            expect(findHeaderSearchAutocompleteItems().exists()).toBe(showAutocomplete);
-          });
+        it(`should${showAutocomplete ? '' : ' not'} render the Autocomplete Dropdown Items`, () => {
+          expect(findHeaderSearchAutocompleteItems().exists()).toBe(showAutocomplete);
+        });
 
-          it(`should${
-            showDropdownNavigation ? '' : ' not'
-          } render the Dropdown Navigation Component`, () => {
-            expect(findDropdownKeyboardNavigation().exists()).toBe(showDropdownNavigation);
-          });
+        it(`should render the Dropdown Navigation Component`, () => {
+          expect(findDropdownKeyboardNavigation().exists()).toBe(true);
         });
-      },
-    );
+      });
+    });
 
     describe.each`
       username         | showDropdown | expectedDesc
@@ -185,12 +195,18 @@ describe('HeaderSearchApp', () => {
     `(
       'Search Results Description',
       ({ username, showDropdown, search, loading, searchOptions, expectedDesc }) => {
-        describe(`search is ${search}, loading is ${loading}, and showSearchDropdown is ${
-          Boolean(username) && showDropdown
-        }`, () => {
+        describe(`search is "${search}", loading is ${loading}, and showSearchDropdown is ${showDropdown}`, () => {
           beforeEach(() => {
             window.gon.current_username = username;
-            createComponent({ search, loading }, { searchOptions: () => searchOptions });
+            createComponent(
+              {
+                search,
+                loading,
+              },
+              {
+                searchOptions: () => searchOptions,
+              },
+            );
             findHeaderSearchInput().vm.$emit(showDropdown ? 'click' : '');
           });
 
@@ -200,6 +216,121 @@ describe('HeaderSearchApp', () => {
         });
       },
     );
+
+    describe('input box', () => {
+      describe.each`
+        search         | searchOptions                      | hasToken
+        ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[0]]} | ${true}
+        ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[1]]} | ${true}
+        ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[2]]} | ${true}
+        ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[3]]} | ${true}
+        ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[4]]} | ${true}
+        ${'te'}        | ${[MOCK_SCOPED_SEARCH_OPTIONS[5]]} | ${false}
+        ${'x'}         | ${[]}                              | ${false}
+      `('token', ({ search, searchOptions, hasToken }) => {
+        beforeEach(() => {
+          window.gon.current_username = MOCK_USERNAME;
+          createComponent(
+            { search },
+            {
+              searchOptions: () => searchOptions,
+            },
+          );
+        });
+
+        it(`${hasToken ? 'is' : 'is NOT'} rendered when data set has type "${
+          searchOptions[0]?.html_id
+        }"`, () => {
+          expect(findScopeToken().exists()).toBe(hasToken);
+        });
+
+        it(`text ${hasToken ? 'is correctly' : 'is NOT'} rendered when text is "${
+          searchOptions[0]?.scope || searchOptions[0]?.description
+        }"`, () => {
+          expect(findScopeToken().exists() && findScopeToken().text()).toBe(
+            formatScopeName(searchOptions[0]?.scope || searchOptions[0]?.description),
+          );
+        });
+      });
+    });
+
+    describe('form wrapper', () => {
+      describe.each`
+        searchContext               | search         | searchOptions
+        ${MOCK_SEARCH_CONTEXT_FULL} | ${null}        | ${[]}
+        ${MOCK_SEARCH_CONTEXT_FULL} | ${MOCK_SEARCH} | ${[]}
+        ${MOCK_SEARCH_CONTEXT_FULL} | ${MOCK_SEARCH} | ${MOCK_SCOPED_SEARCH_OPTIONS}
+        ${null}                     | ${MOCK_SEARCH} | ${MOCK_SCOPED_SEARCH_OPTIONS}
+        ${null}                     | ${null}        | ${MOCK_SCOPED_SEARCH_OPTIONS}
+        ${null}                     | ${null}        | ${[]}
+      `('', ({ searchContext, search, searchOptions }) => {
+        beforeEach(() => {
+          window.gon.current_username = MOCK_USERNAME;
+
+          createComponent({ search, searchContext }, { searchOptions: () => searchOptions });
+
+          findHeaderSearchInput().vm.$emit('click');
+        });
+
+        const hasIcon = Boolean(searchContext?.group);
+        const isSearching = Boolean(search);
+        const isActive = Boolean(searchOptions.length > 0);
+
+        it(`${hasIcon ? 'with' : 'without'} search context classes contain "${
+          hasIcon ? 'has-icon' : 'has-no-icon'
+        }"`, () => {
+          const iconClassRegex = hasIcon ? 'has-icon' : 'has-no-icon';
+          expect(findHeaderSearchForm().classes()).toContain(iconClassRegex);
+        });
+
+        it(`${isSearching ? 'with' : 'without'} search string classes contain "${
+          isSearching ? 'is-searching' : 'is-not-searching'
+        }"`, () => {
+          const iconClassRegex = isSearching ? 'is-searching' : 'is-not-searching';
+          expect(findHeaderSearchForm().classes()).toContain(iconClassRegex);
+        });
+
+        it(`${isActive ? 'with' : 'without'} search results classes contain "${
+          isActive ? 'is-active' : 'is-not-active'
+        }"`, () => {
+          const iconClassRegex = isActive ? 'is-active' : 'is-not-active';
+          expect(findHeaderSearchForm().classes()).toContain(iconClassRegex);
+        });
+      });
+    });
+
+    describe.each`
+      search         | searchOptions                      | hasIcon  | iconName
+      ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[0]]} | ${true}  | ${ICON_PROJECT}
+      ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[2]]} | ${true}  | ${ICON_GROUP}
+      ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[3]]} | ${true}  | ${ICON_SUBGROUP}
+      ${MOCK_SEARCH} | ${[MOCK_SCOPED_SEARCH_OPTIONS[4]]} | ${false} | ${false}
+    `('token', ({ search, searchOptions, hasIcon, iconName }) => {
+      beforeEach(() => {
+        window.gon.current_username = MOCK_USERNAME;
+        createComponent(
+          { search },
+          {
+            searchOptions: () => searchOptions,
+          },
+        );
+      });
+
+      it(`icon for data set type "${searchOptions[0]?.html_id}" ${
+        hasIcon ? 'is' : 'is NOT'
+      } rendered`, () => {
+        expect(findScopeToken().findComponent(GlIcon).exists()).toBe(hasIcon);
+      });
+
+      it(`render ${iconName ? `"${iconName}"` : 'NO'} icon for data set type "${
+        searchOptions[0]?.html_id
+      }"`, () => {
+        expect(
+          findScopeToken().findComponent(GlIcon).exists() &&
+            findScopeToken().findComponent(GlIcon).attributes('name'),
+        ).toBe(iconName);
+      });
+    });
   });
 
   describe('events', () => {
@@ -285,18 +416,20 @@ describe('HeaderSearchApp', () => {
   });
 
   describe('computed', () => {
-    describe('currentFocusedOption', () => {
-      const MOCK_INDEX = 1;
-
+    describe.each`
+      MOCK_INDEX          | search
+      ${1}                | ${null}
+      ${SEARCH_BOX_INDEX} | ${'test'}
+      ${2}                | ${'test1'}
+    `('currentFocusedOption', ({ MOCK_INDEX, search }) => {
       beforeEach(() => {
-        createComponent();
+        createComponent({ search });
         window.gon.current_username = MOCK_USERNAME;
         findHeaderSearchInput().vm.$emit('click');
       });
 
-      it(`when currentFocusIndex changes to ${MOCK_INDEX} updates the data to searchOptions[${MOCK_INDEX}]`, async () => {
+      it(`when currentFocusIndex changes to ${MOCK_INDEX} updates the data to searchOptions[${MOCK_INDEX}]`, () => {
         findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX);
-        await nextTick();
         expect(wrapper.vm.currentFocusedOption).toBe(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX]);
       });
     });
@@ -308,15 +441,25 @@ describe('HeaderSearchApp', () => {
         createComponent();
       });
 
-      it('onKey-enter submits a search', async () => {
+      it('onKey-enter submits a search', () => {
         findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
 
-        await nextTick();
-
         expect(visitUrl).toHaveBeenCalledWith(MOCK_SEARCH_QUERY);
       });
     });
 
+    describe('with less than min characters and no dropdown results', () => {
+      beforeEach(() => {
+        createComponent({ search: 'x' });
+      });
+
+      it('onKey-enter will NOT submit a search', () => {
+        findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
+
+        expect(visitUrl).not.toHaveBeenCalledWith(MOCK_SEARCH_QUERY);
+      });
+    });
+
     describe('with currentFocusedOption', () => {
       const MOCK_INDEX = 1;
 
@@ -326,9 +469,9 @@ describe('HeaderSearchApp', () => {
         findHeaderSearchInput().vm.$emit('click');
       });
 
-      it('onKey-enter clicks the selected dropdown item rather than submitting a search', async () => {
+      it('onKey-enter clicks the selected dropdown item rather than submitting a search', () => {
         findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX);
-        await nextTick();
+
         findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
         expect(visitUrl).toHaveBeenCalledWith(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX].url);
       });
diff --git a/spec/frontend/header_search/components/header_search_scoped_items_spec.js b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
index 8788fb23458b3ede29b6c3e8ee05c2e053aa3b2d..2db9f71d70267bbd1954c4f31c9dd7461594708f 100644
--- a/spec/frontend/header_search/components/header_search_scoped_items_spec.js
+++ b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
@@ -1,9 +1,11 @@
-import { GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
+import { GlDropdownItem, GlToken, GlIcon } from '@gitlab/ui';
 import { shallowMount } from '@vue/test-utils';
 import Vue from 'vue';
 import Vuex from 'vuex';
 import { trimText } from 'helpers/text_helper';
 import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue';
+import { truncate } from '~/lib/utils/text_utility';
+import { MSG_IN_ALL_GITLAB, SCOPE_TOKEN_MAX_LENGTH } from '~/header_search/constants';
 import {
   MOCK_SEARCH,
   MOCK_SCOPED_SEARCH_OPTIONS,
@@ -41,9 +43,12 @@ describe('HeaderSearchScopedItems', () => {
   });
 
   const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
-  const findGlDropdownDivider = () => wrapper.findComponent(GlDropdownDivider);
   const findFirstDropdownItem = () => findDropdownItems().at(0);
   const findDropdownItemTitles = () => findDropdownItems().wrappers.map((w) => trimText(w.text()));
+  const findScopeTokens = () => wrapper.findAllComponents(GlToken);
+  const findScopeTokensText = () => findScopeTokens().wrappers.map((w) => trimText(w.text()));
+  const findScopeTokensIcons = () =>
+    findScopeTokens().wrappers.map((w) => w.findAllComponents(GlIcon));
   const findDropdownItemAriaLabels = () =>
     findDropdownItems().wrappers.map((w) => trimText(w.attributes('aria-label')));
   const findDropdownItemLinks = () => findDropdownItems().wrappers.map((w) => w.attributes('href'));
@@ -59,15 +64,31 @@ describe('HeaderSearchScopedItems', () => {
       });
 
       it('renders titles correctly', () => {
+        findDropdownItemTitles().forEach((title) => expect(title).toContain(MOCK_SEARCH));
+      });
+
+      it('renders scope names correctly', () => {
         const expectedTitles = MOCK_SCOPED_SEARCH_OPTIONS.map((o) =>
-          trimText(`"${MOCK_SEARCH}" ${o.description} ${o.scope || ''}`),
+          truncate(trimText(`in ${o.description || o.scope}`), SCOPE_TOKEN_MAX_LENGTH),
         );
-        expect(findDropdownItemTitles()).toStrictEqual(expectedTitles);
+
+        expect(findScopeTokensText()).toStrictEqual(expectedTitles);
+      });
+
+      it('renders scope icons correctly', () => {
+        findScopeTokensIcons().forEach((icon, i) => {
+          const w = icon.wrappers[0];
+          expect(w?.attributes('name')).toBe(MOCK_SCOPED_SEARCH_OPTIONS[i].icon);
+        });
+      });
+
+      it(`renders scope ${MSG_IN_ALL_GITLAB} correctly`, () => {
+        expect(findScopeTokens().at(-1).findComponent(GlIcon).exists()).toBe(false);
       });
 
       it('renders aria-labels correctly', () => {
         const expectedLabels = MOCK_SCOPED_SEARCH_OPTIONS.map((o) =>
-          trimText(`${MOCK_SEARCH} ${o.description} ${o.scope || ''}`),
+          trimText(`${MOCK_SEARCH} ${o.description || o.icon} ${o.scope || ''}`),
         );
         expect(findDropdownItemAriaLabels()).toStrictEqual(expectedLabels);
       });
@@ -98,21 +119,5 @@ describe('HeaderSearchScopedItems', () => {
         });
       });
     });
-
-    describe.each`
-      autosuggestResults                   | showDivider
-      ${[]}                                | ${false}
-      ${MOCK_GROUPED_AUTOCOMPLETE_OPTIONS} | ${true}
-    `('scoped search items', ({ autosuggestResults, showDivider }) => {
-      describe(`when when we have ${autosuggestResults.length} auto-sugest results`, () => {
-        beforeEach(() => {
-          createComponent({}, { autocompleteGroupedSearchOptions: () => autosuggestResults }, {});
-        });
-
-        it(`divider should${showDivider ? '' : ' not'} be shown`, () => {
-          expect(findGlDropdownDivider().exists()).toBe(showDivider);
-        });
-      });
-    });
   });
 });
diff --git a/spec/frontend/header_search/mock_data.js b/spec/frontend/header_search/mock_data.js
index b6f0fdcc29d601ef0d68c16efdeec5dda1b0ac64..8ccd7fb17e3adb23512f8fc545315fe1aaa2716a 100644
--- a/spec/frontend/header_search/mock_data.js
+++ b/spec/frontend/header_search/mock_data.js
@@ -4,9 +4,12 @@ import {
   MSG_MR_ASSIGNED_TO_ME,
   MSG_MR_IM_REVIEWER,
   MSG_MR_IVE_CREATED,
-  MSG_IN_PROJECT,
-  MSG_IN_GROUP,
   MSG_IN_ALL_GITLAB,
+  PROJECTS_CATEGORY,
+  ICON_PROJECT,
+  GROUPS_CATEGORY,
+  ICON_GROUP,
+  ICON_SUBGROUP,
 } from '~/header_search/constants';
 
 export const MOCK_USERNAME = 'anyone';
@@ -27,12 +30,24 @@ export const MOCK_PROJECT = {
   path: '/mock-project',
 };
 
+export const MOCK_PROJECT_LONG = {
+  id: 124,
+  name: 'Mock Project Name That Is Ridiculously Long And It Goes Forever',
+  path: '/mock-project-name-that-is-ridiculously-long-and-it-goes-forever',
+};
+
 export const MOCK_GROUP = {
   id: 321,
   name: 'MockGroup',
   path: '/mock-group',
 };
 
+export const MOCK_SUBGROUP = {
+  id: 322,
+  name: 'MockSubGroup',
+  path: `${MOCK_GROUP}/mock-subgroup`,
+};
+
 export const MOCK_SEARCH_QUERY = 'http://gitlab.com/search?search=test';
 
 export const MOCK_SEARCH = 'test';
@@ -44,6 +59,20 @@ export const MOCK_SEARCH_CONTEXT = {
   group_metadata: {},
 };
 
+export const MOCK_SEARCH_CONTEXT_FULL = {
+  group: {
+    id: 31,
+    name: 'testGroup',
+    full_name: 'testGroup',
+  },
+  group_metadata: {
+    group_path: 'testGroup',
+    name: 'testGroup',
+    issues_path: '/groups/testGroup/-/issues',
+    mr_path: '/groups/testGroup/-/merge_requests',
+  },
+};
+
 export const MOCK_DEFAULT_SEARCH_OPTIONS = [
   {
     html_id: 'default-issues-assigned',
@@ -76,13 +105,51 @@ export const MOCK_SCOPED_SEARCH_OPTIONS = [
   {
     html_id: 'scoped-in-project',
     scope: MOCK_PROJECT.name,
-    description: MSG_IN_PROJECT,
+    scopeCategory: PROJECTS_CATEGORY,
+    icon: ICON_PROJECT,
+    url: MOCK_PROJECT.path,
+  },
+  {
+    html_id: 'scoped-in-project-long',
+    scope: MOCK_PROJECT_LONG.name,
+    scopeCategory: PROJECTS_CATEGORY,
+    icon: ICON_PROJECT,
+    url: MOCK_PROJECT_LONG.path,
+  },
+  {
+    html_id: 'scoped-in-group',
+    scope: MOCK_GROUP.name,
+    scopeCategory: GROUPS_CATEGORY,
+    icon: ICON_GROUP,
+    url: MOCK_GROUP.path,
+  },
+  {
+    html_id: 'scoped-in-subgroup',
+    scope: MOCK_SUBGROUP.name,
+    scopeCategory: GROUPS_CATEGORY,
+    icon: ICON_SUBGROUP,
+    url: MOCK_SUBGROUP.path,
+  },
+  {
+    html_id: 'scoped-in-all',
+    description: MSG_IN_ALL_GITLAB,
+    url: MOCK_ALL_PATH,
+  },
+];
+
+export const MOCK_SCOPED_SEARCH_OPTIONS_DEF = [
+  {
+    html_id: 'scoped-in-project',
+    scope: MOCK_PROJECT.name,
+    scopeCategory: PROJECTS_CATEGORY,
+    icon: ICON_PROJECT,
     url: MOCK_PROJECT.path,
   },
   {
     html_id: 'scoped-in-group',
     scope: MOCK_GROUP.name,
-    description: MSG_IN_GROUP,
+    scopeCategory: GROUPS_CATEGORY,
+    icon: ICON_GROUP,
     url: MOCK_GROUP.path,
   },
   {
diff --git a/spec/frontend/header_search/store/getters_spec.js b/spec/frontend/header_search/store/getters_spec.js
index d3510de14397b8f77421feb98fe1be763aee1330..c76be3c03602625f7b773383fb0699c9ccbd08ad 100644
--- a/spec/frontend/header_search/store/getters_spec.js
+++ b/spec/frontend/header_search/store/getters_spec.js
@@ -9,6 +9,7 @@ import {
   MOCK_SEARCH_CONTEXT,
   MOCK_DEFAULT_SEARCH_OPTIONS,
   MOCK_SCOPED_SEARCH_OPTIONS,
+  MOCK_SCOPED_SEARCH_OPTIONS_DEF,
   MOCK_PROJECT,
   MOCK_GROUP,
   MOCK_ALL_PATH,
@@ -284,7 +285,7 @@ describe('Header Search Store Getters', () => {
 
     it('returns the correct array', () => {
       expect(getters.scopedSearchOptions(state, mockGetters)).toStrictEqual(
-        MOCK_SCOPED_SEARCH_OPTIONS,
+        MOCK_SCOPED_SEARCH_OPTIONS_DEF,
       );
     });
   });
@@ -308,6 +309,11 @@ describe('Header Search Store Getters', () => {
     ${MOCK_SEARCH} | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${MOCK_SCOPED_SEARCH_OPTIONS} | ${[]}                                | ${MOCK_SCOPED_SEARCH_OPTIONS}
     ${MOCK_SEARCH} | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${[]}                         | ${MOCK_GROUPED_AUTOCOMPLETE_OPTIONS} | ${MOCK_SORTED_AUTOCOMPLETE_OPTIONS}
     ${MOCK_SEARCH} | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${MOCK_SCOPED_SEARCH_OPTIONS} | ${MOCK_GROUPED_AUTOCOMPLETE_OPTIONS} | ${MOCK_SCOPED_SEARCH_OPTIONS.concat(MOCK_SORTED_AUTOCOMPLETE_OPTIONS)}
+    ${1}           | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${[]}                         | ${[]}                                | ${[]}
+    ${'('}         | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${[]}                         | ${[]}                                | ${[]}
+    ${'t'}         | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${MOCK_SCOPED_SEARCH_OPTIONS} | ${MOCK_GROUPED_AUTOCOMPLETE_OPTIONS} | ${MOCK_SORTED_AUTOCOMPLETE_OPTIONS}
+    ${'te'}        | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${MOCK_SCOPED_SEARCH_OPTIONS} | ${MOCK_GROUPED_AUTOCOMPLETE_OPTIONS} | ${MOCK_SORTED_AUTOCOMPLETE_OPTIONS}
+    ${'tes'}       | ${MOCK_DEFAULT_SEARCH_OPTIONS} | ${MOCK_SCOPED_SEARCH_OPTIONS} | ${MOCK_GROUPED_AUTOCOMPLETE_OPTIONS} | ${MOCK_SCOPED_SEARCH_OPTIONS.concat(MOCK_SORTED_AUTOCOMPLETE_OPTIONS)}
   `(
     'searchOptions',
     ({
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index 4117d577f20be8c23a0078a6414e9b44d7f51ed2..1ead1fc9b8bee308b28c3e36bf755eefe64ba76c 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -741,7 +741,7 @@ def simple_sanitize(str)
         let(:for_group) { true }
 
         it 'adds the :group and :group_metadata correctly to hash' do
-          expect(header_search_context[:group]).to eq({ id: group.id, name: group.name })
+          expect(header_search_context[:group]).to eq({ id: group.id, name: group.name, full_name: group.full_name })
           expect(header_search_context[:group_metadata]).to eq(group_metadata)
         end