diff --git a/app/assets/javascripts/usage_quotas/constants.js b/app/assets/javascripts/usage_quotas/constants.js
index acb9e1d7264d22e863eb201ef459eecbf537fe0f..2c11bcedacdeccca31d50c1d3238babaa7b538aa 100644
--- a/app/assets/javascripts/usage_quotas/constants.js
+++ b/app/assets/javascripts/usage_quotas/constants.js
@@ -6,4 +6,7 @@ export const USAGE_QUOTAS_SUBTITLE = s__(
   'UsageQuota|Usage of group resources across the projects in the %{namespaceName} group',
 );
 
+export const GROUP_VIEW_TYPE = 'group_view';
+export const PROJECT_VIEW_TYPE = 'project_view';
+
 export const STORAGE_TAB_METADATA_EL_SELECTOR = '#js-namespace-storage-app';
diff --git a/ee/app/assets/javascripts/usage_quotas/constants.js b/ee/app/assets/javascripts/usage_quotas/constants.js
index 039721ff505d68f63887b1d84a2b085f94491b61..1a317945c2f9e70de8ac6008770bfc08787387e9 100644
--- a/ee/app/assets/javascripts/usage_quotas/constants.js
+++ b/ee/app/assets/javascripts/usage_quotas/constants.js
@@ -6,3 +6,6 @@ export const USAGE_BY_PROJECT_HEADER = s__('UsageQuota|Usage by project');
 export const PIPELINES_TAB_METADATA_EL_SELECTOR = '#js-pipeline-usage-app';
 export const SEATS_TAB_METADATA_EL_SELECTOR = '#js-seat-usage-app';
 export const CODE_SUGGESTIONS_TAB_METADATA_EL_SELECTOR = '#js-code-suggestions-usage-app';
+export const GROUP_TRANSFER_TAB_METADATA_EL_SELECTOR = '#js-group-transfer-app';
+
+export const PROJECT_TRANSFER_TAB_METADATA_EL_SELECTOR = '#js-project-transfer-app';
diff --git a/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js b/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js
index 32d7c6f4340a9065e2144b7ea6c1e8c63f69f6b2..d4b7d0b778fe466a478eafcf400b1d4f36686b6a 100644
--- a/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js
+++ b/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js
@@ -1,11 +1,12 @@
 import { __ } from '~/locale';
 import { storageTabMetadata } from '~/usage_quotas/group_view_metadata';
-import { STORAGE_TAB_METADATA_EL_SELECTOR } from '~/usage_quotas/constants';
+import { STORAGE_TAB_METADATA_EL_SELECTOR, GROUP_VIEW_TYPE } from '~/usage_quotas/constants';
 import PipelineUsageApp from './pipelines/components/app.vue';
 import { parseProvideData as parseStorageTabProvideData } from './storage/utils';
 import { parseProvideData as parsePipelinesTabProvideData } from './pipelines/utils';
 import { PIPELINES_TAB_METADATA_EL_SELECTOR } from './constants';
 import { getCodeSuggestionsTabMetadata } from './code_suggestions/tab_metadata';
+import { getTransferTabMetadata } from './transfer/tab_metadata';
 import { getSeatTabMetadata } from './seats/tab_metadata';
 
 export const usageQuotasViewProvideData = {
@@ -29,4 +30,5 @@ export const usageQuotasTabsMetadata = [
   getCodeSuggestionsTabMetadata(),
   getPipelineTabMetadata(),
   storageTabMetadata,
+  getTransferTabMetadata(GROUP_VIEW_TYPE),
 ];
diff --git a/ee/app/assets/javascripts/usage_quotas/transfer/index.js b/ee/app/assets/javascripts/usage_quotas/transfer/index.js
index 1ba23f6a7bd3f15bf44e89f5cf7a0e58d8d48303..a7b7d5e20a94c60e446d90a7f87879b9a94af5e5 100644
--- a/ee/app/assets/javascripts/usage_quotas/transfer/index.js
+++ b/ee/app/assets/javascripts/usage_quotas/transfer/index.js
@@ -1,56 +1,24 @@
 import Vue from 'vue';
 import VueApollo from 'vue-apollo';
-import createDefaultClient from '~/lib/graphql';
-import GroupTransferApp from './components/group_transfer_app.vue';
-import ProjectTransferApp from './components/project_transfer_app.vue';
+import { GROUP_VIEW_TYPE, PROJECT_VIEW_TYPE } from '~/usage_quotas/constants';
+import { getTransferTabMetadata } from './tab_metadata';
 
 export const initGroupTransferApp = () => {
-  const el = document.getElementById('js-group-transfer-app');
+  const transferTabMetadata = getTransferTabMetadata(GROUP_VIEW_TYPE, true);
 
-  if (!el) return false;
+  if (!transferTabMetadata) return false;
 
   Vue.use(VueApollo);
 
-  const apolloProvider = new VueApollo({
-    defaultClient: createDefaultClient(),
-  });
-
-  const { fullPath } = el.dataset;
-
-  return new Vue({
-    el,
-    apolloProvider,
-    provide: {
-      fullPath,
-    },
-    render(createElement) {
-      return createElement(GroupTransferApp);
-    },
-  });
+  return new Vue(transferTabMetadata.component);
 };
 
 export const initProjectTransferApp = () => {
-  const el = document.getElementById('js-project-transfer-app');
+  const transferTabMetadata = getTransferTabMetadata(PROJECT_VIEW_TYPE, true);
 
-  if (!el) return false;
+  if (!transferTabMetadata) return false;
 
   Vue.use(VueApollo);
 
-  const apolloProvider = new VueApollo({
-    defaultClient: createDefaultClient(),
-  });
-
-  const { fullPath } = el.dataset;
-
-  return new Vue({
-    el,
-    apolloProvider,
-    name: 'ProjectTransferApp',
-    provide: {
-      fullPath,
-    },
-    render(createElement) {
-      return createElement(ProjectTransferApp);
-    },
-  });
+  return new Vue(transferTabMetadata.component);
 };
diff --git a/ee/app/assets/javascripts/usage_quotas/transfer/tab_metadata.js b/ee/app/assets/javascripts/usage_quotas/transfer/tab_metadata.js
new file mode 100644
index 0000000000000000000000000000000000000000..af60e8e1eec4748ea8471f902dcc80840decf0f4
--- /dev/null
+++ b/ee/app/assets/javascripts/usage_quotas/transfer/tab_metadata.js
@@ -0,0 +1,55 @@
+import VueApollo from 'vue-apollo';
+import { __ } from '~/locale';
+import createDefaultClient from '~/lib/graphql';
+import { GROUP_VIEW_TYPE, PROJECT_VIEW_TYPE } from '~/usage_quotas/constants';
+import {
+  GROUP_TRANSFER_TAB_METADATA_EL_SELECTOR,
+  PROJECT_TRANSFER_TAB_METADATA_EL_SELECTOR,
+} from '../constants';
+import GroupTransferApp from './components/group_transfer_app.vue';
+import ProjectTransferApp from './components/project_transfer_app.vue';
+
+export const parseProvideData = (el) => {
+  const { fullPath } = el.dataset;
+  return {
+    fullPath,
+  };
+};
+
+export const getTransferTabMetadata = (viewType, withMountElement = false) => {
+  let elSelector;
+  let vueComponent;
+
+  if (viewType === GROUP_VIEW_TYPE) {
+    elSelector = GROUP_TRANSFER_TAB_METADATA_EL_SELECTOR;
+    vueComponent = GroupTransferApp;
+  } else if (viewType === PROJECT_VIEW_TYPE) {
+    elSelector = PROJECT_TRANSFER_TAB_METADATA_EL_SELECTOR;
+    vueComponent = ProjectTransferApp;
+  }
+
+  const el = document.querySelector(elSelector);
+
+  if (!el) return false;
+
+  const apolloProvider = new VueApollo({
+    defaultClient: createDefaultClient(),
+  });
+
+  const transferTabMetadata = {
+    title: __('Transfer'),
+    component: {
+      name: 'TransferTab',
+      apolloProvider,
+      provide: parseProvideData(el),
+      render(createElement) {
+        return createElement(vueComponent);
+      },
+    },
+  };
+  if (withMountElement) {
+    transferTabMetadata.component.el = el;
+  }
+
+  return transferTabMetadata;
+};
diff --git a/ee/app/views/groups/usage_quotas/index.html.haml b/ee/app/views/groups/usage_quotas/index.html.haml
index 9a8df050dd14f94474cc258db25684d89fc94dde..b8f0788220e7037b86b6d41609ec06a1f6e8ff75 100644
--- a/ee/app/views/groups/usage_quotas/index.html.haml
+++ b/ee/app/views/groups/usage_quotas/index.html.haml
@@ -22,6 +22,8 @@
     - if can? current_user, :admin_ci_minutes, @group
       #js-pipeline-usage-app{ data: pipeline_usage_app_data(@group) }
     #js-namespace-storage-app{ data: storage_usage_app_data(@group) }
+    - if Feature.enabled?(:data_transfer_monitoring, @group)
+      #js-group-transfer-app{ data: group_transfer_app_data(@group) }
 - else
   - if show_product_purchase_success_alert?
     = render 'product_purchase_success_alert', product_name: params[:purchased_product]