diff --git a/ee/app/assets/javascripts/product_analytics/graphql/mutations/get_project_jitsu_key.query.graphql b/ee/app/assets/javascripts/product_analytics/graphql/mutations/get_project_jitsu_key.query.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..ca21c54eb0bbb5ef5c57cc4703bfa61b94b00ed8
--- /dev/null
+++ b/ee/app/assets/javascripts/product_analytics/graphql/mutations/get_project_jitsu_key.query.graphql
@@ -0,0 +1,6 @@
+query getProjectJitsuKey($projectPath: ID!) {
+  project(fullPath: $projectPath) {
+    id
+    jitsuKey
+  }
+}
diff --git a/ee/app/assets/javascripts/product_analytics/graphql/mutations/initialize_product_analytics.mutation.graphql b/ee/app/assets/javascripts/product_analytics/graphql/mutations/initialize_product_analytics.mutation.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..5c463724fb601a6071c4757d6641df22de2ccd20
--- /dev/null
+++ b/ee/app/assets/javascripts/product_analytics/graphql/mutations/initialize_product_analytics.mutation.graphql
@@ -0,0 +1,9 @@
+mutation initializeProductAnalytics($projectPath: ID!) {
+  projectInitializeProductAnalytics(input: { projectPath: $projectPath }) {
+    project {
+      id
+      fullPath
+    }
+    errors
+  }
+}
diff --git a/ee/app/assets/javascripts/product_analytics/index.js b/ee/app/assets/javascripts/product_analytics/index.js
index 4552049113aaa0db2d4623a0e4c8b5212468a1f4..c9539ce5523f28de9710b8c390ea3446269185bb 100644
--- a/ee/app/assets/javascripts/product_analytics/index.js
+++ b/ee/app/assets/javascripts/product_analytics/index.js
@@ -1,4 +1,6 @@
 import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
 import AnalyticsApp from './product_analytics_app.vue';
 import createRouter from './router';
 
@@ -12,16 +14,24 @@ export default () => {
   const {
     jitsuKey,
     projectId,
+    projectFullPath,
     jitsuHost,
     jitsuProjectId,
     chartEmptyStateIllustrationPath,
   } = el.dataset;
+  Vue.use(VueApollo);
+
+  const apolloProvider = new VueApollo({
+    defaultClient: createDefaultClient(),
+  });
 
   return new Vue({
     el,
+    apolloProvider,
     router: createRouter(),
     provide: {
       jitsuKey,
+      projectFullPath,
       projectId,
       jitsuHost,
       jitsuProjectId,
diff --git a/ee/app/assets/javascripts/product_analytics/onboarding/components/onboarding_empty_state.vue b/ee/app/assets/javascripts/product_analytics/onboarding/components/onboarding_empty_state.vue
new file mode 100644
index 0000000000000000000000000000000000000000..df1623269b34abc8c9de00488ef0cfaab39ac8dc
--- /dev/null
+++ b/ee/app/assets/javascripts/product_analytics/onboarding/components/onboarding_empty_state.vue
@@ -0,0 +1,59 @@
+<script>
+import { GlButton, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { EMPTY_STATE_I18N } from '../constants';
+
+export default {
+  name: 'AnalyticsEmptyState',
+  components: {
+    GlButton,
+    GlEmptyState,
+    GlLoadingIcon,
+  },
+  inject: {
+    chartEmptyStateIllustrationPath: {
+      type: String,
+    },
+  },
+  props: {
+    loading: {
+      type: Boolean,
+      required: false,
+      default: false,
+    },
+  },
+  computed: {
+    title() {
+      return this.loading ? EMPTY_STATE_I18N.loading.title : EMPTY_STATE_I18N.empty.title;
+    },
+    description() {
+      return this.loading
+        ? EMPTY_STATE_I18N.loading.description
+        : EMPTY_STATE_I18N.empty.description;
+    },
+  },
+  i18n: EMPTY_STATE_I18N,
+  docsPath: helpPagePath('user/product_analytics/index'),
+};
+</script>
+
+<template>
+  <gl-empty-state :title="title" :svg-path="chartEmptyStateIllustrationPath">
+    <template #description>
+      <p class="gl-max-w-80">
+        {{ description }}
+      </p>
+    </template>
+    <template #actions>
+      <template v-if="!loading">
+        <gl-button variant="confirm" data-testid="setup-btn" @click="$emit('initialize')">
+          {{ $options.i18n.empty.setUpBtnText }}
+        </gl-button>
+        <gl-button :href="$options.docsPath" data-testid="learn-more-btn">
+          {{ $options.i18n.empty.learnMoreBtnText }}
+        </gl-button>
+      </template>
+      <gl-loading-icon v-else size="lg" class="gl-mt-5" />
+    </template>
+  </gl-empty-state>
+</template>
diff --git a/ee/app/assets/javascripts/product_analytics/onboarding/constants.js b/ee/app/assets/javascripts/product_analytics/onboarding/constants.js
index d8526ffb4dd758497eea6aad38ec006dd17b7b77..45ef74d45b0edca02755582e9b86ff21aebfa761 100644
--- a/ee/app/assets/javascripts/product_analytics/onboarding/constants.js
+++ b/ee/app/assets/javascripts/product_analytics/onboarding/constants.js
@@ -1,3 +1,5 @@
+import { s__, __ } from '~/locale';
+
 export const INSTALL_NPM_PACKAGE = `yarn add @gitlab/application-sdk-js
 
 --
@@ -17,3 +19,22 @@ export const HTML_SCRIPT_SETUP = `<script src="https://unpkg.com/@gitlab/applica
     applicationId: '$applicationId',
     host: '$host',
 });</script>`;
+
+export const JITSU_KEY_CHECK_DELAY = 1000;
+
+export const EMPTY_STATE_I18N = {
+  empty: {
+    title: s__('Product Analytics|Analyze your product with Product Analytics'),
+    description: s__(
+      'Product Analytics|Set up Product Analytics to track how your product is performing. Combine it with your GitLab data to better understand where you can improve your product and development processes.',
+    ),
+    setUpBtnText: s__('Product Analytics|Set up product analytics'),
+    learnMoreBtnText: __('Learn more'),
+  },
+  loading: {
+    title: s__('Product Analytics|Creating your product analytics instance...'),
+    description: s__(
+      'Product Analytics|This might take a while, feel free to navigate away from this page and come back later.',
+    ),
+  },
+};
diff --git a/ee/app/assets/javascripts/product_analytics/onboarding/onboarding_view.vue b/ee/app/assets/javascripts/product_analytics/onboarding/onboarding_view.vue
index 16d5df2fcc4e46a28cff36f2c4b35c1751fc64a1..c25396b024656df3d558b9d120cabf957633fa45 100644
--- a/ee/app/assets/javascripts/product_analytics/onboarding/onboarding_view.vue
+++ b/ee/app/assets/javascripts/product_analytics/onboarding/onboarding_view.vue
@@ -1,43 +1,96 @@
 <script>
-import { GlEmptyState } from '@gitlab/ui';
-import { s__, __ } from '~/locale';
-import { helpPagePath } from '~/helpers/help_page_helper';
+import { createAlert } from '~/flash';
+import initializeProductAnalyticsMutation from '../graphql/mutations/initialize_product_analytics.mutation.graphql';
+import getProjectJitsuKeyQuery from '../graphql/mutations/get_project_jitsu_key.query.graphql';
+import OnboardingEmptyState from './components/onboarding_empty_state.vue';
+import { JITSU_KEY_CHECK_DELAY } from './constants';
 
 export default {
   name: 'ProductAnalyticsOnboardingView',
   components: {
-    GlEmptyState,
+    OnboardingEmptyState,
   },
   inject: {
-    chartEmptyStateIllustrationPath: {
+    projectFullPath: {
       type: String,
     },
   },
-  i18n: {
-    title: s__('Product Analytics|Analyze your product with Product Analytics'),
-    description: s__(
-      'Product Analytics|Set up Product Analytics to track how your product is performing. Combine it with your GitLab data to better understand where you can improve your product and development processes.',
-    ),
-    setUpBtnText: s__('Product Analytics|Set up product analytics...'),
-    learnMoreBtnText: __('Learn more'),
+  data() {
+    return {
+      creatingInstance: false,
+      jitsuKey: null,
+      pollJitsuKey: false,
+    };
+  },
+  apollo: {
+    jitsuKey: {
+      query: getProjectJitsuKeyQuery,
+      variables() {
+        return {
+          projectPath: this.projectFullPath,
+        };
+      },
+      pollInterval: JITSU_KEY_CHECK_DELAY,
+      update({ project }) {
+        const { jitsuKey } = project || {};
+
+        this.pollJitsuKey = !jitsuKey;
+
+        return jitsuKey;
+      },
+      skip() {
+        return !this.pollJitsuKey;
+      },
+      error(err) {
+        this.showError(err);
+        this.pollJitsuKey = false;
+      },
+    },
+  },
+  computed: {
+    loading() {
+      return this.creatingInstance || this.pollJitsuKey;
+    },
+  },
+  methods: {
+    showError(error, captureError = true) {
+      createAlert({
+        message: error.message,
+        captureError,
+        error,
+      });
+    },
+    async initializeProductAnalytics() {
+      this.creatingInstance = true;
+      try {
+        const { data } = await this.$apollo.mutate({
+          mutation: initializeProductAnalyticsMutation,
+          variables: {
+            projectPath: this.projectFullPath,
+          },
+          context: {
+            isSingleRequest: true,
+          },
+        });
+
+        const [error] = data?.projectInitializeProductAnalytics?.errors || [];
+
+        if (error) {
+          this.showError(new Error(error), false);
+        } else {
+          this.pollJitsuKey = true;
+        }
+      } catch (err) {
+        // TODO: Update to show the tracking codes view when no error in https://gitlab.com/gitlab-org/gitlab/-/issues/381320
+        this.showError(err);
+      } finally {
+        this.creatingInstance = false;
+      }
+    },
   },
-  docsPath: helpPagePath('user/product_analytics/index'),
 };
 </script>
 
 <template>
-  <gl-empty-state
-    :title="$options.i18n.title"
-    :svg-path="chartEmptyStateIllustrationPath"
-    :primary-button-text="$options.i18n.setUpBtnText"
-    primary-button-link="#"
-    :secondary-button-text="$options.i18n.learnMoreBtnText"
-    :secondary-button-link="$options.docsPath"
-  >
-    <template #description>
-      <p class="gl-max-w-80">
-        {{ $options.i18n.description }}
-      </p>
-    </template>
-  </gl-empty-state>
+  <onboarding-empty-state :loading="loading" @initialize="initializeProductAnalytics" />
 </template>
diff --git a/ee/app/views/projects/product_analytics/dashboards.haml b/ee/app/views/projects/product_analytics/dashboards.haml
index 16875fbf180af82dfa2808a544735e9e8521767f..405d2cf40862e267a138957c518a40d16bed6d01 100644
--- a/ee/app/views/projects/product_analytics/dashboards.haml
+++ b/ee/app/views/projects/product_analytics/dashboards.haml
@@ -7,6 +7,7 @@
     jitsu_host: Gitlab::CurrentSettings.current_application_settings.jitsu_host,
     jitsu_project_id: Gitlab::CurrentSettings.current_application_settings.jitsu_project_xid,
     chart_empty_state_illustration_path: image_path('illustrations/chart-empty-state.svg'),
+    project_full_path: @project.full_path,
   }
 }
   = gl_loading_icon(size: 'lg', css_class: 'gl-my-7')
diff --git a/ee/spec/features/projects/product_analytics/dashboards_spec.rb b/ee/spec/features/projects/product_analytics/dashboards_spec.rb
index ef2e1f94a4a344fcf5ffa5f20af1b2a8650c3355..8b954b90eeb8378ca685de2fd743553960aa19f5 100644
--- a/ee/spec/features/projects/product_analytics/dashboards_spec.rb
+++ b/ee/spec/features/projects/product_analytics/dashboards_spec.rb
@@ -30,7 +30,7 @@
     end
   end
 
-  shared_examples 'renders the onboarding view' do
+  shared_examples 'renders the onboarding empty state' do
     before do
       visit_page
     end
@@ -93,7 +93,38 @@
         end
 
         context 'without the Jitsu key' do
-          it_behaves_like 'renders the onboarding view'
+          it_behaves_like 'renders the onboarding empty state'
+
+          context 'when setting up a new instance' do
+            before do
+              visit_page
+              click_button s_('Product Analytics|Set up product analytics')
+            end
+
+            it 'renders the creating instance loading screen' do
+              expect(page).to have_content(s_('Product Analytics|Creating your product analytics instance...'))
+            end
+
+            # TODO: Update to show the tracking codes view when no error in https://gitlab.com/gitlab-org/gitlab/-/issues/381320
+            it 'returns back to the onboarding empty state after creating the new instance' do
+              wait_for_requests
+
+              expect(page).to have_content(s_('Product Analytics|Analyze your product with Product Analytics'))
+            end
+
+            context 'when a new instance has already been initialized' do
+              before do
+                visit_page
+              end
+
+              it 'renders an error alert when setting up a new instance' do
+                click_button s_('Product Analytics|Set up product analytics')
+
+                expect(find('[data-testid="alert-danger"]'))
+                  .to have_text(/Product analytics initialization is already (completed|in progress)/)
+              end
+            end
+          end
         end
 
         context 'with the Jitsu key' do
diff --git a/ee/spec/frontend/product_analytics/mock_data.js b/ee/spec/frontend/product_analytics/mock_data.js
new file mode 100644
index 0000000000000000000000000000000000000000..faca2fdfb310793e383671a3ed2ff9695c4a2da5
--- /dev/null
+++ b/ee/spec/frontend/product_analytics/mock_data.js
@@ -0,0 +1,20 @@
+export const createInstanceResponse = (errors = []) => ({
+  data: {
+    projectInitializeProductAnalytics: {
+      project: {
+        id: 'gid://gitlab/Project/2',
+        fullPath: '',
+      },
+      errors,
+    },
+  },
+});
+
+export const getJitsuKeyResponse = (jitsuKey = null) => ({
+  data: {
+    project: {
+      id: 'gid://gitlab/Project/2',
+      jitsuKey,
+    },
+  },
+});
diff --git a/ee/spec/frontend/product_analytics/onboarding/components/onboarding_empty_state_spec.js b/ee/spec/frontend/product_analytics/onboarding/components/onboarding_empty_state_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..350b61f48ba3dea794b32d9b9cae06720d843b9d
--- /dev/null
+++ b/ee/spec/frontend/product_analytics/onboarding/components/onboarding_empty_state_spec.js
@@ -0,0 +1,79 @@
+import { GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
+import OnboardingEmptyState from 'ee/product_analytics/onboarding/components/onboarding_empty_state.vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { TEST_HOST } from 'spec/test_constants';
+import { EMPTY_STATE_I18N } from 'ee/product_analytics/onboarding/constants';
+
+describe('OnboardingEmptyState', () => {
+  let wrapper;
+
+  const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+  const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+  const findSetupBtn = () => wrapper.findByTestId('setup-btn');
+  const findLearnMoreBtn = () => wrapper.findByTestId('learn-more-btn');
+
+  const createWrapper = (props = {}) => {
+    wrapper = shallowMountExtended(OnboardingEmptyState, {
+      provide: {
+        chartEmptyStateIllustrationPath: TEST_HOST,
+      },
+      propsData: {
+        ...props,
+      },
+    });
+  };
+
+  describe('default behaviour', () => {
+    beforeEach(() => {
+      createWrapper();
+    });
+
+    it('should render the empty state with expected props', () => {
+      const emptyState = findEmptyState();
+
+      expect(emptyState.props()).toMatchObject({
+        title: EMPTY_STATE_I18N.empty.title,
+        svgPath: TEST_HOST,
+      });
+      expect(emptyState.text()).toContain(EMPTY_STATE_I18N.empty.description);
+      expect(findSetupBtn().text()).toBe(EMPTY_STATE_I18N.empty.setUpBtnText);
+      expect(findLearnMoreBtn().text()).toBe(EMPTY_STATE_I18N.empty.learnMoreBtnText);
+      expect(findLearnMoreBtn().attributes('href')).toBe('/help/user/product_analytics/index');
+    });
+
+    it('should emit `initialize` when the setup button is clicked', () => {
+      findSetupBtn().vm.$emit('click');
+
+      expect(wrapper.emitted('initialize')).toStrictEqual([[]]);
+    });
+
+    it('does not render the loading icon', () => {
+      expect(findLoadingIcon().exists()).toBe(false);
+    });
+  });
+
+  describe('when loading', () => {
+    beforeEach(() => {
+      createWrapper({ loading: true });
+    });
+
+    it('should render the loading state', () => {
+      const emptyState = findEmptyState();
+
+      expect(emptyState.props()).toMatchObject({
+        title: EMPTY_STATE_I18N.loading.title,
+        svgPath: TEST_HOST,
+      });
+      expect(emptyState.text()).toContain(EMPTY_STATE_I18N.loading.description);
+    });
+
+    it('renders the loading icon', () => {
+      expect(findLoadingIcon().exists()).toBe(true);
+    });
+
+    it('does not render the buttons', () => {
+      expect(findSetupBtn().exists()).toBe(false);
+      expect(findLearnMoreBtn().exists()).toBe(false);
+    });
+  });
+});
diff --git a/ee/spec/frontend/product_analytics/onboarding/onboarding_view_spec.js b/ee/spec/frontend/product_analytics/onboarding/onboarding_view_spec.js
index 5f6cf79368c16913e9925b5259934b03a427c3d0..af39e42e1fad2449badb8ff10cd4418db0c59a06 100644
--- a/ee/spec/frontend/product_analytics/onboarding/onboarding_view_spec.js
+++ b/ee/spec/frontend/product_analytics/onboarding/onboarding_view_spec.js
@@ -1,38 +1,154 @@
-import { GlEmptyState } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
+import Vue from 'vue';
 import ProductAnalyticsOnboardingView from 'ee/product_analytics/onboarding/onboarding_view.vue';
+import OnboardingEmptyState from 'ee/product_analytics/onboarding/components/onboarding_empty_state.vue';
+import initializeProductAnalyticsMutation from 'ee/product_analytics/graphql/mutations/initialize_product_analytics.mutation.graphql';
+import getProjectJitsuKeyQuery from 'ee/product_analytics/graphql/mutations/get_project_jitsu_key.query.graphql';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
 import { TEST_HOST } from 'spec/test_constants';
+import waitForPromises from 'helpers/wait_for_promises';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { createAlert } from '~/flash';
+import { JITSU_KEY_CHECK_DELAY } from 'ee/product_analytics/onboarding/constants';
+import { createInstanceResponse, getJitsuKeyResponse } from '../mock_data';
+
+Vue.use(VueApollo);
+
+jest.mock('~/flash');
 
 describe('ProductAnalyticsOnboardingView', () => {
   let wrapper;
 
-  const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+  const fatalError = new Error('GraphQL networkError');
+  const apiErrorMsg = 'Product analytics initialization is already complete';
+  const jitsuKey = 'valid-jitsu-key';
+  const mockCreateInstanceSuccess = jest.fn().mockResolvedValue(createInstanceResponse());
+  const mockCreateInstanceLoading = jest.fn().mockResolvedValue(new Promise(() => {}));
+  const mockCreateInstanceApiError = jest
+    .fn()
+    .mockResolvedValue(createInstanceResponse([apiErrorMsg]));
+  const mockCreateInstanceFatalError = jest.fn().mockRejectedValue(fatalError);
+  const mockGetJitsuKeyHasKeySuccess = jest.fn().mockResolvedValue(getJitsuKeyResponse(jitsuKey));
+  const mockGetJitsuKeyHasKeySuccessRetry = jest
+    .fn()
+    .mockResolvedValueOnce(getJitsuKeyResponse(null))
+    .mockResolvedValueOnce(getJitsuKeyResponse(jitsuKey));
+  const mockGetJitsuKeyError = jest.fn().mockRejectedValue(fatalError);
+
+  const findEmptyState = () => wrapper.findComponent(OnboardingEmptyState);
 
-  const createWrapper = () => {
+  const createWrapper = (handlers) => {
     wrapper = shallowMountExtended(ProductAnalyticsOnboardingView, {
+      apolloProvider: createMockApollo(handlers),
       provide: {
         chartEmptyStateIllustrationPath: TEST_HOST,
+        projectFullPath: 'group-1/project-1',
       },
     });
   };
 
+  const waitForApolloTimers = async () => {
+    jest.advanceTimersByTime(JITSU_KEY_CHECK_DELAY);
+    return waitForPromises();
+  };
+
+  afterEach(() => {
+    createAlert.mockClear();
+  });
+
   describe('when mounted', () => {
     beforeEach(() => {
       createWrapper();
     });
 
-    it('should render the empty state with expected props', () => {
-      const emptyState = findEmptyState();
+    it('should render the empty state that is not loading', () => {
+      expect(findEmptyState().props('loading')).toBe(false);
+    });
+
+    it('has a polling interval for querying the jitsu key', () => {
+      expect(wrapper.vm.$apollo.queries.jitsuKey.options.pollInterval).toBe(JITSU_KEY_CHECK_DELAY);
+    });
+  });
+
+  describe('when creating an instance', () => {
+    it('should show loading while the instance is initializing', async () => {
+      createWrapper([[initializeProductAnalyticsMutation, mockCreateInstanceLoading]]);
+
+      await findEmptyState().vm.$emit('initialize');
+
+      expect(findEmptyState().props('loading')).toBe(true);
+    });
+
+    it('should show loading and poll for the jitsu key while it is null', async () => {
+      createWrapper([
+        [initializeProductAnalyticsMutation, mockCreateInstanceSuccess],
+        [getProjectJitsuKeyQuery, mockGetJitsuKeyHasKeySuccessRetry],
+      ]);
+
+      findEmptyState().vm.$emit('initialize');
+
+      await waitForPromises();
+
+      expect(mockGetJitsuKeyHasKeySuccessRetry.mock.calls).toHaveLength(1);
+      expect(findEmptyState().props('loading')).toBe(true);
+
+      await waitForApolloTimers();
+
+      expect(mockGetJitsuKeyHasKeySuccessRetry.mock.calls).toHaveLength(2);
+      expect(findEmptyState().props('loading')).toBe(false);
+    });
+
+    it('should return the jitsu key if creating an instance is successful', async () => {
+      createWrapper([
+        [initializeProductAnalyticsMutation, mockCreateInstanceSuccess],
+        [getProjectJitsuKeyQuery, mockGetJitsuKeyHasKeySuccess],
+      ]);
+
+      findEmptyState().vm.$emit('initialize');
 
-      expect(emptyState.props()).toMatchObject({
-        title: ProductAnalyticsOnboardingView.i18n.title,
-        svgPath: TEST_HOST,
-        primaryButtonText: ProductAnalyticsOnboardingView.i18n.setUpBtnText,
-        primaryButtonLink: '#',
-        secondaryButtonText: ProductAnalyticsOnboardingView.i18n.learnMoreBtnText,
-        secondaryButtonLink: ProductAnalyticsOnboardingView.docsPath,
+      await waitForPromises();
+
+      expect(mockGetJitsuKeyHasKeySuccess).toHaveBeenCalledTimes(1);
+      expect(findEmptyState().props('loading')).toBe(false);
+    });
+
+    it('should show the error if getting the jitsu key throws an error', async () => {
+      createWrapper([
+        [initializeProductAnalyticsMutation, mockCreateInstanceSuccess],
+        [getProjectJitsuKeyQuery, mockGetJitsuKeyError],
+      ]);
+
+      findEmptyState().vm.$emit('initialize');
+
+      await waitForPromises();
+
+      expect(createAlert).toHaveBeenCalledWith({
+        message: fatalError.message,
+        captureError: true,
+        error: fatalError,
       });
-      expect(emptyState.text()).toContain(ProductAnalyticsOnboardingView.i18n.description);
+    });
+
+    describe('when a create instance error occurs', () => {
+      it.each`
+        type          | mockError                       | alertError                | captureError
+        ${'instance'} | ${mockCreateInstanceFatalError} | ${fatalError}             | ${true}
+        ${'api'}      | ${mockCreateInstanceApiError}   | ${new Error(apiErrorMsg)} | ${false}
+      `(
+        'should create an alert for $type errors',
+        async ({ mockError, alertError, captureError }) => {
+          createWrapper([[initializeProductAnalyticsMutation, mockError]]);
+
+          findEmptyState().vm.$emit('initialize');
+          await waitForPromises();
+
+          expect(createAlert).toHaveBeenCalledWith({
+            message: alertError.message,
+            captureError,
+            error: alertError,
+          });
+        },
+      );
     });
   });
 });
diff --git a/ee/spec/frontend/product_analytics/product_analytics_app_spec.js b/ee/spec/frontend/product_analytics/product_analytics_app_spec.js
index 89cd8b18b5c822ad5d4af046264465489c1327e2..cc7315bcf216e31313361fc52c50a8047d0c004a 100644
--- a/ee/spec/frontend/product_analytics/product_analytics_app_spec.js
+++ b/ee/spec/frontend/product_analytics/product_analytics_app_spec.js
@@ -28,11 +28,12 @@ describe('ProductAnalyticsApp', () => {
     wrapper = shallowMount(AnalyticsApp, {
       router: createRouter(),
       provide: {
+        chartEmptyStateIllustrationPath: TEST_HOST,
         jitsuKey: '123',
         projectId: '1',
         jitsuHost: TEST_HOST,
         jitsuProjectId: '',
-        chartEmptyStateIllustrationPath: TEST_HOST,
+        projectFullPath: 'group-1/project-1',
         ...provided,
       },
     });
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ca17d528fc377d488a18c11020aacce65702a614..14c025ef39205be99ff7f38e8145dcdf7eedc456 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -31810,6 +31810,9 @@ msgstr ""
 msgid "Product Analytics|Analyze your product with Product Analytics"
 msgstr ""
 
+msgid "Product Analytics|Creating your product analytics instance..."
+msgstr ""
+
 msgid "Product Analytics|For the product analytics dashboard to start showing you some data, you need to add the analytics tracking code to your project."
 msgstr ""
 
@@ -31831,7 +31834,7 @@ msgstr ""
 msgid "Product Analytics|Set up Product Analytics to track how your product is performing. Combine it with your GitLab data to better understand where you can improve your product and development processes."
 msgstr ""
 
-msgid "Product Analytics|Set up product analytics..."
+msgid "Product Analytics|Set up product analytics"
 msgstr ""
 
 msgid "Product Analytics|Steps to add product analytics as a CommonJS module"
@@ -31846,6 +31849,9 @@ msgstr ""
 msgid "Product Analytics|The host to send all tracking events to"
 msgstr ""
 
+msgid "Product Analytics|This might take a while, feel free to navigate away from this page and come back later."
+msgstr ""
+
 msgid "Product Analytics|To instrument your application, select one of the options below. After an option has been instrumented and data is being collected, this page will progress to the next step."
 msgstr ""