diff --git a/CHANGELOG b/CHANGELOG
index 2f472f0f7fac5b33057733252651962076a211e6..a244f5959e6695e12f52f5e461fadcd948603884 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 minerva-front (18.0.2) stable; urgency=medium
   * Bug fix: Terms of Service modal is not hidden by Select project modal when
     login via ORCID (#305)
+  * Bug fix: when downloading map there was missing spinner indicating the
+    download is in progress (#297)
 
  -- Piotr Gawron <piotr.gawron@uni.lu>  Wed, 30 Oct 2024 13:00:00 +0200
 
diff --git a/src/components/Map/Drawer/SubmapsDrawer/SubmapItem/DownloadSubmap/DownloadSubmap.component.tsx b/src/components/Map/Drawer/SubmapsDrawer/SubmapItem/DownloadSubmap/DownloadSubmap.component.tsx
index 01587d62f8bbd459f9aff42cd0f7502c1051ec8a..316528128b6a0dec97b0fd16761961f47b2ed60e 100644
--- a/src/components/Map/Drawer/SubmapsDrawer/SubmapItem/DownloadSubmap/DownloadSubmap.component.tsx
+++ b/src/components/Map/Drawer/SubmapsDrawer/SubmapItem/DownloadSubmap/DownloadSubmap.component.tsx
@@ -2,18 +2,34 @@ import { formatsHandlersSelector } from '@/redux/configuration/configuration.sel
 import { Button } from '@/shared/Button';
 import { useSelect } from 'downshift';
 import { useSelector } from 'react-redux';
+import Image from 'next/image';
+import spinnerIcon from '@/assets/vectors/icons/spinner.svg';
+import { useState } from 'react';
+import { downloadFileFromUrl } from '@/redux/export/export.utils';
 import { SUBMAP_DOWNLOAD_HANDLERS_NAMES } from './DownloadSubmap.constants';
 import { useGetSubmapDownloadUrl } from './utils/useGetSubmapDownloadUrl';
 
-export const DownloadSubmap = (): JSX.Element => {
+export const DownloadSubmap = (): React.ReactNode => {
   const formatsHandlers = useSelector(formatsHandlersSelector);
   const formatsHandlersItems = Object.entries(formatsHandlers);
   const getSubmapDownloadUrl = useGetSubmapDownloadUrl();
 
-  const { isOpen, getToggleButtonProps, getMenuProps } = useSelect({
+  const [isDownloading, setIsDownloading] = useState<boolean>(false);
+
+  const { isOpen, getToggleButtonProps, getMenuProps, closeMenu } = useSelect({
     items: formatsHandlersItems,
   });
 
+  const downloadSubmap = (handler: string) => {
+    return function () {
+      closeMenu();
+      setIsDownloading(true);
+      downloadFileFromUrl(getSubmapDownloadUrl({ handler })).finally(function () {
+        setIsDownloading(false);
+      });
+    };
+  };
+
   return (
     <div className="relative">
       <Button
@@ -22,6 +38,15 @@ export const DownloadSubmap = (): JSX.Element => {
         className="mr-4"
         {...getToggleButtonProps()}
       >
+        {isDownloading && (
+          <Image
+            src={spinnerIcon}
+            alt="spinner icon"
+            height={12}
+            width={12}
+            className="mr-5 animate-spin"
+          />
+        )}
         Download
       </Button>
       <ul
@@ -34,14 +59,13 @@ export const DownloadSubmap = (): JSX.Element => {
         {isOpen &&
           formatsHandlersItems.map(([formatId, handler]) => (
             <li key={formatId}>
-              <a
-                className="flex flex-col border-t px-4 py-2 shadow-sm"
-                href={getSubmapDownloadUrl({ handler })}
-                target="_blank"
-                download
+              <Button
+                variantStyles="ghost"
+                className="flex w-full flex-col border-t px-4 py-2 shadow-sm"
+                onClick={downloadSubmap(handler)}
               >
-                <span>{SUBMAP_DOWNLOAD_HANDLERS_NAMES[formatId]}</span>
-              </a>
+                {SUBMAP_DOWNLOAD_HANDLERS_NAMES[formatId]}
+              </Button>
             </li>
           ))}
       </ul>
diff --git a/src/redux/export/export.utils.ts b/src/redux/export/export.utils.ts
index 60cba1fd90f1fe16a31e44a266f7bc8dd41206a6..921c381286d677a9ee075eaa0b8afd91cb4f6ccb 100644
--- a/src/redux/export/export.utils.ts
+++ b/src/redux/export/export.utils.ts
@@ -1,3 +1,5 @@
+import axios from 'axios';
+
 export const downloadFileFromBlob = (data: string, filename: string): void => {
   const url = window.URL.createObjectURL(new Blob([data]));
   const link = document.createElement('a');
@@ -7,3 +9,27 @@ export const downloadFileFromBlob = (data: string, filename: string): void => {
   link.click();
   link.remove();
 };
+
+export const downloadFileFromUrl = async (url: string): Promise<void> => {
+  const genericAxios = axios.create();
+
+  const response = await genericAxios.get(url, {
+    withCredentials: true,
+    responseType: 'arraybuffer',
+  });
+
+  const content = Buffer.from(response.data, 'binary');
+
+  let filename = 'file.xml';
+  if (response.headers && response.headers['content-type'] === 'application/zip') {
+    filename = 'file.zip';
+  }
+
+  const tmpUrl = window.URL.createObjectURL(new Blob([content], { type: 'application/zip' }));
+  const link = document.createElement('a');
+  link.href = tmpUrl;
+  link.setAttribute('download', filename);
+  document.body.appendChild(link);
+  link.click();
+  link.remove();
+};