diff --git a/src/components/Map/Drawer/Drawer.component.test.tsx b/src/components/Map/Drawer/Drawer.component.test.tsx
index 185ccbae910b0813e2a240508f78fdaacde166e1..a0cbbdfc2e08e3a39b9b1cd658d5e895f0e811c3 100644
--- a/src/components/Map/Drawer/Drawer.component.test.tsx
+++ b/src/components/Map/Drawer/Drawer.component.test.tsx
@@ -1,11 +1,22 @@
-import { openSearchDrawerWithSelectedTab, openSubmapsDrawer } from '@/redux/drawer/drawer.slice';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { reactionsFixture } from '@/models/fixtures/reactionFixture';
+import {
+  openReactionDrawerById,
+  openSearchDrawerWithSelectedTab,
+  openSubmapsDrawer,
+} from '@/redux/drawer/drawer.slice';
+import { getReactionsByIds } from '@/redux/reactions/reactions.thunks';
 import { StoreType } from '@/redux/store';
-import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
-import { act, fireEvent, render, screen } from '@testing-library/react';
+import {
+  InitialStoreState,
+  getReduxWrapperWithStore,
+} from '@/utils/testing/getReduxWrapperWithStore';
+import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
+import type {} from 'redux-thunk/extend-redux';
 import { Drawer } from './Drawer.component';
 
-const renderComponent = (): { store: StoreType } => {
-  const { Wrapper, store } = getReduxWrapperWithStore();
+const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStore);
   return (
     render(
       <Wrapper>
@@ -77,4 +88,25 @@ describe('Drawer - component', () => {
       expect(screen.getByTestId('submap-drawer')).toBeInTheDocument();
     });
   });
+
+  describe('reaction drawer', () => {
+    it('should open drawer and display reaction', async () => {
+      const { id } = reactionsFixture[FIRST_ARRAY_ELEMENT];
+
+      const { store } = renderComponent({
+        reactions: {
+          data: reactionsFixture,
+          loading: 'succeeded',
+          error: { message: '', name: '' },
+        },
+      });
+
+      expect(screen.queryByTestId('reaction-drawer')).not.toBeInTheDocument();
+
+      store.dispatch(getReactionsByIds([id]));
+      store.dispatch(openReactionDrawerById(id));
+
+      await waitFor(() => expect(screen.getByTestId('reaction-drawer')).toBeInTheDocument());
+    });
+  });
 });
diff --git a/src/components/Map/Drawer/Drawer.component.tsx b/src/components/Map/Drawer/Drawer.component.tsx
index 269281bd16f691fb84569c7ba489964751128432..abc4e3a2880001d5e5463ec393963f139b54b308 100644
--- a/src/components/Map/Drawer/Drawer.component.tsx
+++ b/src/components/Map/Drawer/Drawer.component.tsx
@@ -2,6 +2,7 @@ import { DRAWER_ROLE } from '@/components/Map/Drawer/Drawer.constants';
 import { drawerSelector } from '@/redux/drawer/drawer.selectors';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { twMerge } from 'tailwind-merge';
+import { ReactionDrawer } from './ReactionDrawer';
 import { SearchDrawerWrapper as SearchDrawerContent } from './SearchDrawerWrapper';
 import { SubmapsDrawer } from './SubmapsDrawer';
 
@@ -11,13 +12,14 @@ export const Drawer = (): JSX.Element => {
   return (
     <div
       className={twMerge(
-        'absolute bottom-0 left-[88px] top-[104px] z-10 h-calc-drawer w-[432px] -translate-x-full transform bg-white-pearl text-font-500 transition-all duration-500',
+        'absolute bottom-0 left-[88px] top-[104px] z-10 h-calc-drawer w-[432px] -translate-x-full transform border border-divide bg-white-pearl text-font-500 transition-all duration-500',
         isOpen && 'translate-x-0',
       )}
       role={DRAWER_ROLE}
     >
       {isOpen && drawerName === 'search' && <SearchDrawerContent />}
       {isOpen && drawerName === 'submaps' && <SubmapsDrawer />}
+      {isOpen && drawerName === 'reaction' && <ReactionDrawer />}
     </div>
   );
 };
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..1a635a0b5ac357f43962460455aa1c9683780c41
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.test.tsx
@@ -0,0 +1,116 @@
+import { SECOND_ARRAY_ELEMENT } from '@/constants/common';
+import { reactionsFixture } from '@/models/fixtures/reactionFixture';
+import { DRAWER_INITIAL_STATE } from '@/redux/drawer/drawer.constants';
+import { StoreType } from '@/redux/store';
+import {
+  InitialStoreState,
+  getReduxWrapperWithStore,
+} from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen } from '@testing-library/react';
+import { ReactionDrawer } from './ReactionDrawer.component';
+import { DEFAULT_REFERENCE_SOURCE } from './ReactionDrawer.constants';
+
+const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
+
+  return (
+    render(
+      <Wrapper>
+        <ReactionDrawer />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('ReactionDrawer - component', () => {
+  beforeEach(() => {
+    jest.resetAllMocks();
+    jest.clearAllMocks();
+  });
+
+  describe("when there's NO matching reaction", () => {
+    beforeEach(() =>
+      renderComponent({
+        reactions: {
+          data: [],
+          loading: 'succeeded',
+          error: { message: '', name: '' },
+        },
+        drawer: DRAWER_INITIAL_STATE,
+      }),
+    );
+
+    it('should not show drawer content', () => {
+      expect(screen.queryByText('Reaction:')).toBeNull();
+      expect(screen.queryByText('Type:')).toBeNull();
+      expect(screen.queryByText('Annotations:')).toBeNull();
+      expect(screen.queryByText('Source:')).toBeNull();
+    });
+  });
+
+  describe('when there IS a matching reaction', () => {
+    const reaction = reactionsFixture[SECOND_ARRAY_ELEMENT];
+
+    const filteredReferences = reaction.references.filter(
+      ref => ref.link !== null && ref.link !== undefined,
+    );
+
+    const referencesTextHref: [string, string][] = filteredReferences.map(ref => [
+      `${ref.type} (${ref.id})`,
+      ref.link as string,
+    ]);
+
+    const referencesSources: string[] = filteredReferences.map(
+      ref => ref.annotatorClassName || DEFAULT_REFERENCE_SOURCE,
+    );
+
+    beforeEach(() =>
+      renderComponent({
+        reactions: {
+          data: reactionsFixture,
+          loading: 'succeeded',
+          error: { message: '', name: '' },
+        },
+        drawer: {
+          ...DRAWER_INITIAL_STATE,
+          reactionDrawerState: {
+            reactionId: reaction.id,
+          },
+        },
+      }),
+    );
+
+    it('should show drawer header', () => {
+      expect(screen.getByText('Reaction:')).toBeInTheDocument();
+      expect(screen.getByText(reaction.reactionId)).toBeInTheDocument();
+    });
+
+    it('should show drawer reaction type', () => {
+      expect(screen.getByText('Type:')).toBeInTheDocument();
+      expect(screen.getByText(reaction.type)).toBeInTheDocument();
+    });
+
+    it('should show drawer reaction annotations title', () => {
+      expect(screen.getByText('Annotations:')).toBeInTheDocument();
+    });
+
+    it.each(referencesSources)('should show drawer reaction source for source=%s', source => {
+      expect(screen.getByText(`Source: ${source}`, { exact: false })).toBeInTheDocument();
+    });
+
+    it.each(referencesTextHref)(
+      'should show drawer reaction reference with text=%s, href=%s',
+      (refText, href) => {
+        const linkReferenceSpan = screen.getByText(refText, { exact: false });
+        const linkReferenceAnchor = linkReferenceSpan.closest('a');
+
+        expect(linkReferenceSpan).toBeInTheDocument();
+        expect(linkReferenceAnchor).toBeInTheDocument();
+        expect(linkReferenceAnchor?.href).toBe(`${href}/`); // component render adds trailing slash
+      },
+    );
+  });
+});
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..9f6a8c4c3a130a2986a2a7cb15879fa93cb6cca9
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.component.tsx
@@ -0,0 +1,38 @@
+import {
+  currentDrawerReactionGroupedReferencesSelector,
+  currentDrawerReactionSelector,
+} from '@/redux/reactions/reactions.selector';
+import { DrawerHeading } from '@/shared/DrawerHeading';
+import { useSelector } from 'react-redux';
+import { ReferenceGroup } from './ReferenceGroup';
+
+export const ReactionDrawer = (): React.ReactNode => {
+  const reaction = useSelector(currentDrawerReactionSelector);
+  const referencesGrouped = useSelector(currentDrawerReactionGroupedReferencesSelector);
+
+  if (!reaction) {
+    return null;
+  }
+
+  return (
+    <div className="h-full max-h-full" data-testid="reaction-drawer">
+      <DrawerHeading
+        title={
+          <>
+            <span className="font-normal">Reaction:</span>&nbsp;{reaction.reactionId}
+          </>
+        }
+      />
+      <div className="flex flex-col gap-6 p-6">
+        <div className="text-sm font-normal">
+          Type: <b className="font-semibold">{reaction.type}</b>
+        </div>
+        <hr className="border-b border-b-divide" />
+        <h3 className="font-semibold">Annotations:</h3>
+        {referencesGrouped.map(group => (
+          <ReferenceGroup key={group.source} group={group} />
+        ))}
+      </div>
+    </div>
+  );
+};
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.constants.ts b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ea80cbf1cd8944995ff783aa2fd0dd73a3d57c9
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReactionDrawer.constants.ts
@@ -0,0 +1 @@
+export const DEFAULT_REFERENCE_SOURCE = 'Annotated by curator';
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.test.tsx b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..838f1d50e65f88462e99d31713bcd202b4661dcf
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.test.tsx
@@ -0,0 +1,111 @@
+import { StoreType } from '@/redux/store';
+import { ReferenceFiltered } from '@/types/reference';
+import {
+  InitialStoreState,
+  getReduxWrapperWithStore,
+} from '@/utils/testing/getReduxWrapperWithStore';
+import { render, screen } from '@testing-library/react';
+import { Props, ReferenceGroup } from './ReferenceGroup.component';
+
+const renderComponent = (
+  props: Props,
+  initialStoreState: InitialStoreState = {},
+): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
+
+  return (
+    render(
+      <Wrapper>
+        <ReferenceGroup {...props} />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('ReactionDrawer - component', () => {
+  beforeEach(() => {
+    jest.resetAllMocks();
+    jest.clearAllMocks();
+  });
+
+  const singleReference = {
+    link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+    article: {
+      title:
+        'The nutrient-responsive transcription factor TFE3 promotes autophagy, lysosomal biogenesis, and clearance of cellular debris.',
+      authors: [
+        'Martina JA',
+        ' Diab HI',
+        ' Lishu L',
+        ' Jeong-A L',
+        ' Patange S',
+        ' Raben N',
+        ' Puertollano R.',
+      ],
+      journal: 'Science signaling',
+      year: 2014,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+      pubmedId: '24448649',
+      citationCount: 321,
+    },
+    type: 'PUBMED',
+    resource: '24448649',
+    id: 154973,
+    annotatorClassName: '',
+  };
+
+  const cases: [string, ReferenceFiltered[]][] = [
+    ['', [singleReference]],
+    [
+      'source1',
+      [
+        {
+          ...singleReference,
+          annotatorClassName: 'source1',
+          id: 1,
+        },
+        {
+          ...singleReference,
+          annotatorClassName: 'source1',
+          id: 2,
+        },
+      ],
+    ],
+    [
+      'source2',
+      [
+        {
+          ...singleReference,
+          annotatorClassName: 'source2',
+          id: 3,
+        },
+      ],
+    ],
+  ];
+
+  it.each(cases)('should show reference group with source=%s', (source, references) => {
+    const referencesTextHref: [string, string][] = references.map(ref => [
+      `${ref.type} (${ref.id})`,
+      ref.link as string,
+    ]);
+
+    renderComponent({
+      group: {
+        source,
+        references,
+      },
+    });
+
+    referencesTextHref.forEach(([refText, href]) => {
+      const linkReferenceSpan = screen.getByText(refText, { exact: false });
+      const linkReferenceAnchor = linkReferenceSpan.closest('a');
+
+      expect(linkReferenceSpan).toBeInTheDocument();
+      expect(linkReferenceAnchor).toBeInTheDocument();
+      expect(linkReferenceAnchor?.href).toBe(`${href}`);
+    });
+  });
+});
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.tsx b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..aab45512ff1b06cdea9eebca337c83f27082939e
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/ReferenceGroup.component.tsx
@@ -0,0 +1,21 @@
+import { Icon } from '@/shared/Icon';
+import { ReferenceGroup as ReferenceGroupType } from '@/types/reference';
+import { DEFAULT_REFERENCE_SOURCE } from '../ReactionDrawer.constants';
+
+export interface Props {
+  group: ReferenceGroupType;
+}
+
+export const ReferenceGroup = ({ group: { source, references } }: Props): JSX.Element => (
+  <>
+    <h3 className="font-semibold">Source: {source || DEFAULT_REFERENCE_SOURCE}</h3>
+    {references.map(({ id, link, type }) => (
+      <a key={id} href={link} target="_blank">
+        <div className="flex justify-between">
+          <span>{`${type} (${id})`}</span>
+          <Icon name="arrow" className="h-6 w-6 fill-font-500" />
+        </div>
+      </a>
+    ))}
+  </>
+);
diff --git a/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/index.ts b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0ac05ab8eb96c1fdf86a0095257838d8de604991
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/ReferenceGroup/index.ts
@@ -0,0 +1 @@
+export { ReferenceGroup } from './ReferenceGroup.component';
diff --git a/src/components/Map/Drawer/ReactionDrawer/index.ts b/src/components/Map/Drawer/ReactionDrawer/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f440178e2344badc1c96e449196e59ac66497ea4
--- /dev/null
+++ b/src/components/Map/Drawer/ReactionDrawer/index.ts
@@ -0,0 +1 @@
+export { ReactionDrawer } from './ReactionDrawer.component';
diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx
index 7a35bafb8e264528fba7a55a258271790172ae00..0d22badc45be8d6f9cd6cf4c68102330b6f399b6 100644
--- a/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx
+++ b/src/components/Map/Drawer/SearchDrawerWrapper/SearchDrawerWrapper.component.test.tsx
@@ -43,6 +43,7 @@ describe('SearchDrawerWrapper - component', () => {
           listOfBioEnitites: [],
           selectedSearchElement: '',
         },
+        reactionDrawerState: {},
       },
     });
 
@@ -61,6 +62,7 @@ describe('SearchDrawerWrapper - component', () => {
           listOfBioEnitites: [],
           selectedSearchElement: '',
         },
+        reactionDrawerState: {},
       },
     });
 
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts
index 701539ac758b99655a2537758fc04bca64f2f4c3..8c3eb1e6f95f2461b398610cf139e1096e50d81c 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleAliasResults.test.ts
@@ -1,4 +1,4 @@
-import { FIRST, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
 import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture';
 import { ELEMENT_SEARCH_RESULT_MOCK_ALIAS } from '@/models/mocks/elementSearchResultMock';
 import { apiPath } from '@/redux/apiPath';
@@ -31,7 +31,7 @@ describe('handleAliasResults - util', () => {
     await waitFor(() => {
       const actions = store.getActions();
       expect(actions.length).toBeGreaterThan(SIZE_OF_EMPTY_ARRAY);
-      expect(actions[FIRST].type).toEqual('project/getMultiBioEntity/pending');
+      expect(actions[FIRST_ARRAY_ELEMENT].type).toEqual('project/getMultiBioEntity/pending');
     });
   });
 });
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts
index 21c6524d2eb8656cf19a870edb07e15d06963d6e..b514095b3654a64d101e79df172d841b60abb01d 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.test.ts
@@ -1,5 +1,5 @@
 /* eslint-disable no-magic-numbers */
-import { SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
 import { bioEntityResponseFixture } from '@/models/fixtures/bioEntityContentsFixture';
 import { reactionsFixture } from '@/models/fixtures/reactionFixture';
 import {
@@ -43,15 +43,22 @@ describe('handleReactionResults - util', () => {
     expect(actions[1].type).toEqual('reactions/getByIds/fulfilled');
   });
 
-  it('should run setBioEntityContent to empty array as second action', () => {
+  it('should run openReactionDrawerById to empty array as second action', () => {
     const actions = store.getActions();
     expect(actions.length).toBeGreaterThan(SIZE_OF_EMPTY_ARRAY);
-    expect(actions[2].type).toEqual('project/getMultiBioEntity/pending');
+    expect(actions[2].type).toEqual('drawer/openReactionDrawerById');
+    expect(actions[2].payload).toEqual(reactionsFixture[FIRST_ARRAY_ELEMENT].id);
   });
 
-  it('should run getBioEntity as third action', () => {
+  it('should run setBioEntityContent to empty array as third action', () => {
     const actions = store.getActions();
     expect(actions.length).toBeGreaterThan(SIZE_OF_EMPTY_ARRAY);
-    expect(actions[3].type).toEqual('project/getBioEntityContents/pending');
+    expect(actions[3].type).toEqual('project/getMultiBioEntity/pending');
+  });
+
+  it('should run getBioEntity as fourth action', () => {
+    const actions = store.getActions();
+    expect(actions.length).toBeGreaterThan(SIZE_OF_EMPTY_ARRAY);
+    expect(actions[4].type).toEqual('project/getBioEntityContents/pending');
   });
 });
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts
index 5c5ae1a20eada4b0349d1b2972059cdb04265d69..55c244ad04bd1a9cb6021085247101025742fa68 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleReactionResults.ts
@@ -1,5 +1,6 @@
-import { FIRST, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT, SIZE_OF_EMPTY_ARRAY } from '@/constants/common';
 import { getMultiBioEntity } from '@/redux/bioEntity/bioEntity.thunks';
+import { openReactionDrawerById } from '@/redux/drawer/drawer.slice';
 import { getReactionsByIds } from '@/redux/reactions/reactions.thunks';
 import { AppDispatch } from '@/redux/store';
 import { ElementSearchResult, Reaction } from '@/types/models';
@@ -15,12 +16,14 @@ export const handleReactionResults =
         return;
       }
 
-      const { products, reactants, modifiers } = payload[FIRST];
+      const reaction = payload[FIRST_ARRAY_ELEMENT];
+      const { products, reactants, modifiers } = reaction;
       const productsIds = products.map(p => p.aliasId);
       const reactantsIds = reactants.map(r => r.aliasId);
       const modifiersIds = modifiers.map(m => m.aliasId);
       const bioEntitiesIds = [...productsIds, ...reactantsIds, ...modifiersIds].map(identifier => String(identifier));
 
+      dispatch(openReactionDrawerById(reaction.id));
       await dispatch(
         getMultiBioEntity({
           searchQueries: bioEntitiesIds,
diff --git a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts
index e60af27ce2a06b6db202af658868857d57b341a7..648457ecab4fb03ddd75a8b69d324377d81d9c39 100644
--- a/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts
+++ b/src/components/Map/MapViewer/utils/listeners/mapSingleClick/handleSearchResultAction.ts
@@ -1,4 +1,4 @@
-import { FIRST } from '@/constants/common';
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
 import { AppDispatch } from '@/redux/store';
 import { ElementSearchResult } from '@/types/models';
 import { handleAliasResults } from './handleAliasResults';
@@ -13,7 +13,7 @@ export const handleSearchResultAction = async ({
   searchResults,
   dispatch,
 }: HandleSearchResultActionInput): Promise<void> => {
-  const closestSearchResult = searchResults[FIRST];
+  const closestSearchResult = searchResults[FIRST_ARRAY_ELEMENT];
   const { type } = closestSearchResult;
   const action = {
     ALIAS: handleAliasResults,
diff --git a/src/constants/common.ts b/src/constants/common.ts
index 1825686b98af79ba59146ff6c567b8a50170940e..973c26af876d5e91f9e0599ff1a21571d96579b5 100644
--- a/src/constants/common.ts
+++ b/src/constants/common.ts
@@ -1,5 +1,6 @@
 export const SIZE_OF_EMPTY_ARRAY = 0;
 export const ZERO = 0;
-export const FIRST = 0;
+export const FIRST_ARRAY_ELEMENT = 0;
 
 export const ONE = 1;
+export const SECOND_ARRAY_ELEMENT = 1;
diff --git a/src/models/mocks/referencesMock.ts b/src/models/mocks/referencesMock.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ce51b43e29b66b0e0266367a6c8772916b7e7a81
--- /dev/null
+++ b/src/models/mocks/referencesMock.ts
@@ -0,0 +1,178 @@
+import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
+import { Reference } from '@/types/models';
+
+export const REFERENCES_MOCK_ALL_VALID: Reference[] = [
+  {
+    link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+    article: {
+      title:
+        'The nutrient-responsive transcription factor TFE3 promotes autophagy, lysosomal biogenesis, and clearance of cellular debris.',
+      authors: [
+        'Martina JA',
+        ' Diab HI',
+        ' Lishu L',
+        ' Jeong-A L',
+        ' Patange S',
+        ' Raben N',
+        ' Puertollano R.',
+      ],
+      journal: 'Science signaling',
+      year: 2014,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+      pubmedId: '24448649',
+      citationCount: 321,
+    },
+    type: 'PUBMED',
+    resource: '24448649',
+    id: 154973,
+    annotatorClassName: '',
+  },
+  {
+    link: 'https://www.ncbi.nlm.nih.gov/pubmed/27299292',
+    article: {
+      title:
+        'Transcription factor EB: from master coordinator of lysosomal pathways to candidate therapeutic target in degenerative storage diseases.',
+      authors: ['Sardiello M.'],
+      journal: 'Annals of the New York Academy of Sciences',
+      year: 2016,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/27299292',
+      pubmedId: '27299292',
+      citationCount: 66,
+    },
+    type: 'PUBMED',
+    resource: '27299292',
+    id: 154974,
+    annotatorClassName: '',
+  },
+  {
+    link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+    article: {
+      title:
+        'The nutrient-responsive transcription factor TFE3 promotes autophagy, lysosomal biogenesis, and clearance of cellular debris.',
+      authors: [
+        'Martina JA',
+        ' Diab HI',
+        ' Lishu L',
+        ' Jeong-A L',
+        ' Patange S',
+        ' Raben N',
+        ' Puertollano R.',
+      ],
+      journal: 'Science signaling',
+      year: 2014,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+      pubmedId: '24448649',
+      citationCount: 321,
+    },
+    type: 'PUBMED',
+    resource: '24448649',
+    id: 154973,
+    annotatorClassName: 'source1',
+  },
+  {
+    link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+    article: {
+      title:
+        'Transcription factor EB: from master coordinator of lysosomal pathways to candidate therapeutic target in degenerative storage diseases.',
+      authors: ['Sardiello M.'],
+      journal: 'Annals of the New York Academy of Sciences',
+      year: 2016,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/27299292',
+      pubmedId: '27299292',
+      citationCount: 66,
+    },
+    type: 'PUBMED',
+    resource: '27299292',
+    id: 154974,
+    annotatorClassName: 'source2',
+  },
+];
+
+export const REFERENCES_MOCK_ALL_INVALID: Reference[] = [
+  {
+    link: null,
+    article: {
+      title:
+        'The nutrient-responsive transcription factor TFE3 promotes autophagy, lysosomal biogenesis, and clearance of cellular debris.',
+      authors: [
+        'Martina JA',
+        ' Diab HI',
+        ' Lishu L',
+        ' Jeong-A L',
+        ' Patange S',
+        ' Raben N',
+        ' Puertollano R.',
+      ],
+      journal: 'Science signaling',
+      year: 2014,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+      pubmedId: '24448649',
+      citationCount: 321,
+    },
+    type: 'PUBMED',
+    resource: '24448649',
+    id: 154973,
+    annotatorClassName: '',
+  },
+  {
+    link: null,
+    article: {
+      title:
+        'Transcription factor EB: from master coordinator of lysosomal pathways to candidate therapeutic target in degenerative storage diseases.',
+      authors: ['Sardiello M.'],
+      journal: 'Annals of the New York Academy of Sciences',
+      year: 2016,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/27299292',
+      pubmedId: '27299292',
+      citationCount: 66,
+    },
+    type: 'PUBMED',
+    resource: '27299292',
+    id: 154974,
+    annotatorClassName: '',
+  },
+  {
+    link: null,
+    article: {
+      title:
+        'The nutrient-responsive transcription factor TFE3 promotes autophagy, lysosomal biogenesis, and clearance of cellular debris.',
+      authors: [
+        'Martina JA',
+        ' Diab HI',
+        ' Lishu L',
+        ' Jeong-A L',
+        ' Patange S',
+        ' Raben N',
+        ' Puertollano R.',
+      ],
+      journal: 'Science signaling',
+      year: 2014,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+      pubmedId: '24448649',
+      citationCount: 321,
+    },
+    type: 'PUBMED',
+    resource: '24448649',
+    id: 154973,
+    annotatorClassName: 'source1',
+  },
+  {
+    link: null,
+    article: {
+      title:
+        'Transcription factor EB: from master coordinator of lysosomal pathways to candidate therapeutic target in degenerative storage diseases.',
+      authors: ['Sardiello M.'],
+      journal: 'Annals of the New York Academy of Sciences',
+      year: 2016,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/27299292',
+      pubmedId: '27299292',
+      citationCount: 66,
+    },
+    type: 'PUBMED',
+    resource: '27299292',
+    id: 154974,
+    annotatorClassName: 'source2',
+  },
+];
+
+export const SINGLE_VALID_REFERENCE = REFERENCES_MOCK_ALL_VALID[FIRST_ARRAY_ELEMENT];
diff --git a/src/models/referenceSchema.ts b/src/models/referenceSchema.ts
index 30a31e287cfdc79348e9655b635a417a0729a34b..44a1e0c6d58c37cc92ef8ec2a0acd796007467fc 100644
--- a/src/models/referenceSchema.ts
+++ b/src/models/referenceSchema.ts
@@ -2,7 +2,7 @@ import { z } from 'zod';
 import { articleSchema } from './articleSchema';
 
 export const referenceSchema = z.object({
-  link: z.string().nullable(),
+  link: z.string().url().nullable(),
   article: articleSchema.optional(),
   type: z.string(),
   resource: z.string(),
diff --git a/src/redux/drawer/drawer.constants.ts b/src/redux/drawer/drawer.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..68d612ac9444f668bcf19cbcbfde1efee4b1c430
--- /dev/null
+++ b/src/redux/drawer/drawer.constants.ts
@@ -0,0 +1,14 @@
+import { DrawerState } from './drawer.types';
+
+export const DRAWER_INITIAL_STATE: DrawerState = {
+  isOpen: false,
+  drawerName: 'none',
+  searchDrawerState: {
+    currentStep: 0,
+    stepType: 'none',
+    selectedValue: undefined,
+    listOfBioEnitites: [],
+    selectedSearchElement: '',
+  },
+  reactionDrawerState: {},
+};
diff --git a/src/redux/drawer/drawer.reducers.test.ts b/src/redux/drawer/drawer.reducers.test.ts
index 5f5986f50ad3c58df43c6cbaccce397d94ac9ae5..8b3558312d380e4217a85f1eea0f6b633700b208 100644
--- a/src/redux/drawer/drawer.reducers.test.ts
+++ b/src/redux/drawer/drawer.reducers.test.ts
@@ -1,7 +1,8 @@
+import { drugFixture } from '@/models/fixtures/drugFixtures';
 import * as toolkitRaw from '@reduxjs/toolkit';
 import { AnyAction } from '@reduxjs/toolkit';
 import type { ToolkitStore } from '@reduxjs/toolkit/dist/configureStore';
-import { drugFixture } from '@/models/fixtures/drugFixtures';
+import { DRAWER_INITIAL_STATE } from './drawer.constants';
 import drawerReducer, {
   closeDrawer,
   displayChemicalsList,
@@ -14,18 +15,6 @@ import drawerReducer, {
 } from './drawer.slice';
 import type { DrawerState } from './drawer.types';
 
-const INITIAL_STATE: DrawerState = {
-  isOpen: false,
-  drawerName: 'none',
-  searchDrawerState: {
-    currentStep: 0,
-    stepType: 'none',
-    selectedValue: undefined,
-    listOfBioEnitites: [],
-    selectedSearchElement: '',
-  },
-};
-
 const STEP = {
   FIRST: 1,
   SECOND: 2,
@@ -56,7 +45,7 @@ describe('drawer reducer', () => {
   it('should match initial state', () => {
     const action = { type: 'unknown' };
 
-    expect(drawerReducer(undefined, action)).toEqual(INITIAL_STATE);
+    expect(drawerReducer(undefined, action)).toEqual(DRAWER_INITIAL_STATE);
   });
 
   it('should update the store after openDrawer action', async () => {
diff --git a/src/redux/drawer/drawer.reducers.ts b/src/redux/drawer/drawer.reducers.ts
index f0546c3176022fc9b90fe1150ce6ec5eab459fef..5aefc95bf503df4b2fd87ea9b7d480c9cd88296b 100644
--- a/src/redux/drawer/drawer.reducers.ts
+++ b/src/redux/drawer/drawer.reducers.ts
@@ -1,6 +1,7 @@
 import { STEP } from '@/constants/searchDrawer';
 import type {
   DrawerState,
+  OpenReactionDrawerByIdAction,
   OpenSearchDrawerWithSelectedTabReducerAction,
 } from '@/redux/drawer/drawer.types';
 import type { DrawerName } from '@/types/drawerName';
@@ -74,3 +75,12 @@ export const displayEntityDetailsReducer = (
   state.searchDrawerState.currentStep = STEP.THIRD;
   state.searchDrawerState.selectedValue = action.payload;
 };
+
+export const openReactionDrawerByIdReducer = (
+  state: DrawerState,
+  action: OpenReactionDrawerByIdAction,
+): void => {
+  state.isOpen = true;
+  state.drawerName = 'reaction';
+  state.reactionDrawerState.reactionId = action.payload;
+};
diff --git a/src/redux/drawer/drawer.selectors.ts b/src/redux/drawer/drawer.selectors.ts
index 66743062f679acf1ae46440fea034599ed46be0b..dc8cb74d8b6e248b999df35cc5f7c501d7dfe281 100644
--- a/src/redux/drawer/drawer.selectors.ts
+++ b/src/redux/drawer/drawer.selectors.ts
@@ -89,3 +89,13 @@ export const resultListSelector = createSelector(
 export const bioEnititiesResultListSelector = createSelector(rootSelector, state => {
   return state.drawer.searchDrawerState.listOfBioEnitites;
 });
+
+export const reactionDrawerStateSelector = createSelector(
+  drawerSelector,
+  state => state.reactionDrawerState,
+);
+
+export const currentDrawerReactionIdSelector = createSelector(
+  reactionDrawerStateSelector,
+  state => state?.reactionId,
+);
diff --git a/src/redux/drawer/drawer.slice.ts b/src/redux/drawer/drawer.slice.ts
index 1ae3ace2709537f7a943ddb6f0f15b9b9a495a14..bf0c2f9fe6b42a3992e71fa0b42642bbc882d4d8 100644
--- a/src/redux/drawer/drawer.slice.ts
+++ b/src/redux/drawer/drawer.slice.ts
@@ -1,4 +1,3 @@
-import { DrawerState } from '@/redux/drawer/drawer.types';
 import { createSlice } from '@reduxjs/toolkit';
 import {
   closeDrawerReducer,
@@ -9,25 +8,15 @@ import {
   displayGroupedSearchResultsReducer,
   displayMirnaListReducer,
   openDrawerReducer,
+  openReactionDrawerByIdReducer,
   openSearchDrawerWithSelectedTabReducer,
   openSubmapsDrawerReducer,
 } from './drawer.reducers';
-
-const initialState: DrawerState = {
-  isOpen: false,
-  drawerName: 'none',
-  searchDrawerState: {
-    currentStep: 0,
-    stepType: 'none',
-    selectedValue: undefined,
-    listOfBioEnitites: [],
-    selectedSearchElement: '',
-  },
-};
+import { DRAWER_INITIAL_STATE } from './drawer.constants';
 
 const drawerSlice = createSlice({
   name: 'drawer',
-  initialState,
+  initialState: DRAWER_INITIAL_STATE,
   reducers: {
     openDrawer: openDrawerReducer,
     openSearchDrawerWithSelectedTab: openSearchDrawerWithSelectedTabReducer,
@@ -39,6 +28,7 @@ const drawerSlice = createSlice({
     displayBioEntitiesList: displayBioEntitiesListReducer,
     displayGroupedSearchResults: displayGroupedSearchResultsReducer,
     displayEntityDetails: displayEntityDetailsReducer,
+    openReactionDrawerById: openReactionDrawerByIdReducer,
   },
 });
 
@@ -53,6 +43,7 @@ export const {
   displayBioEntitiesList,
   displayGroupedSearchResults,
   displayEntityDetails,
+  openReactionDrawerById,
 } = drawerSlice.actions;
 
 export default drawerSlice.reducer;
diff --git a/src/redux/drawer/drawer.types.ts b/src/redux/drawer/drawer.types.ts
index 5660d534bdea32d783957b4824d6e5b0a6ba78ca..3046389c05ccb350d506125d67284c507d62ce80 100644
--- a/src/redux/drawer/drawer.types.ts
+++ b/src/redux/drawer/drawer.types.ts
@@ -10,12 +10,20 @@ export type SearchDrawerState = {
   selectedSearchElement: string;
 };
 
+export type ReactionDrawerState = {
+  reactionId?: number;
+};
+
 export type DrawerState = {
   isOpen: boolean;
   drawerName: DrawerName;
   searchDrawerState: SearchDrawerState;
+  reactionDrawerState: ReactionDrawerState;
 };
 
 export type OpenSearchDrawerWithSelectedTabReducerPayload = string;
 export type OpenSearchDrawerWithSelectedTabReducerAction =
   PayloadAction<OpenSearchDrawerWithSelectedTabReducerPayload>;
+
+export type OpenReactionDrawerByIdPayload = number;
+export type OpenReactionDrawerByIdAction = PayloadAction<OpenReactionDrawerByIdPayload>;
diff --git a/src/redux/drawer/drawerFixture.ts b/src/redux/drawer/drawerFixture.ts
index c6c1c62d511a90ce59ca3d41c4a20f57ff58bf7b..d76275c83846ed547c4c7b8b266fa9c7ee90555f 100644
--- a/src/redux/drawer/drawerFixture.ts
+++ b/src/redux/drawer/drawerFixture.ts
@@ -10,6 +10,7 @@ export const initialStateFixture: DrawerState = {
     listOfBioEnitites: [],
     selectedSearchElement: '',
   },
+  reactionDrawerState: {},
 };
 
 export const openedDrawerSubmapsFixture: DrawerState = {
@@ -22,6 +23,7 @@ export const openedDrawerSubmapsFixture: DrawerState = {
     listOfBioEnitites: [],
     selectedSearchElement: '',
   },
+  reactionDrawerState: {},
 };
 
 export const drawerSearchStepOneFixture: DrawerState = {
@@ -34,6 +36,7 @@ export const drawerSearchStepOneFixture: DrawerState = {
     listOfBioEnitites: [],
     selectedSearchElement: '',
   },
+  reactionDrawerState: {},
 };
 
 export const drawerSearchDrugsStepTwoFixture: DrawerState = {
@@ -46,6 +49,7 @@ export const drawerSearchDrugsStepTwoFixture: DrawerState = {
     listOfBioEnitites: [],
     selectedSearchElement: '',
   },
+  reactionDrawerState: {},
 };
 
 export const drawerSearchChemicalsStepTwoFixture: DrawerState = {
diff --git a/src/redux/reactions/reactions.selector.ts b/src/redux/reactions/reactions.selector.ts
index 1f907b39550b23aacbb831687631e8562eec6a50..8dbc69904a3a2737dbbf9159989b43a3c4f2c2e0 100644
--- a/src/redux/reactions/reactions.selector.ts
+++ b/src/redux/reactions/reactions.selector.ts
@@ -1,7 +1,10 @@
 import { Reaction } from '@/types/models';
 import { createSelector } from '@reduxjs/toolkit';
+import { currentDrawerReactionIdSelector } from '../drawer/drawer.selectors';
 import { currentModelIdSelector } from '../models/models.selectors';
 import { rootSelector } from '../root/root.selectors';
+import { getReferencesWithoutEmptyLink } from './utils/getFilteredReferences';
+import { getReferencesGroupedBySource } from './utils/getGroupedReferences';
 
 export const reactionsSelector = createSelector(rootSelector, state => state.reactions);
 
@@ -17,3 +20,18 @@ export const allReactionsSelectorOfCurrentMap = createSelector(
     return reactions.filter(({ modelId }) => modelId === currentModelId);
   },
 );
+
+export const currentDrawerReactionSelector = createSelector(
+  reactionsDataSelector,
+  currentDrawerReactionIdSelector,
+  (reactions, currentDrawerReactionId) =>
+    reactions.find(({ id }) => id === currentDrawerReactionId),
+);
+
+export const currentDrawerReactionGroupedReferencesSelector = createSelector(
+  currentDrawerReactionSelector,
+  reaction => {
+    const referencesFiltered = getReferencesWithoutEmptyLink(reaction);
+    return getReferencesGroupedBySource(referencesFiltered);
+  },
+);
diff --git a/src/redux/reactions/utils/getFilteredReferences.test.ts b/src/redux/reactions/utils/getFilteredReferences.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b02b2cc3dc556abcfc96ad22e59e6563751dfef7
--- /dev/null
+++ b/src/redux/reactions/utils/getFilteredReferences.test.ts
@@ -0,0 +1,34 @@
+import {
+  REFERENCES_MOCK_ALL_INVALID,
+  REFERENCES_MOCK_ALL_VALID,
+} from '@/models/mocks/referencesMock';
+import { Reaction } from '@/types/models';
+import { ReferenceFiltered } from '@/types/reference';
+import { getReferencesWithoutEmptyLink } from './getFilteredReferences';
+
+describe('getFilteredReferences - subUtil', () => {
+  const cases: [Pick<Reaction, 'references'>, ReferenceFiltered[]][] = [
+    [
+      {
+        references: REFERENCES_MOCK_ALL_VALID,
+      },
+      REFERENCES_MOCK_ALL_VALID as ReferenceFiltered[],
+    ],
+    [
+      {
+        references: REFERENCES_MOCK_ALL_INVALID,
+      },
+      [],
+    ],
+    [
+      {
+        references: [...REFERENCES_MOCK_ALL_VALID, ...REFERENCES_MOCK_ALL_INVALID],
+      },
+      REFERENCES_MOCK_ALL_VALID as ReferenceFiltered[],
+    ],
+  ];
+
+  it.each(cases)('should return valid filtered references', (reaction, result) => {
+    expect(getReferencesWithoutEmptyLink(reaction)).toStrictEqual(result);
+  });
+});
diff --git a/src/redux/reactions/utils/getFilteredReferences.ts b/src/redux/reactions/utils/getFilteredReferences.ts
new file mode 100644
index 0000000000000000000000000000000000000000..987eb1a0637a0b901dcb1a8ea13df76196190ef2
--- /dev/null
+++ b/src/redux/reactions/utils/getFilteredReferences.ts
@@ -0,0 +1,11 @@
+import { Reaction } from '@/types/models';
+import { ReferenceFiltered } from '@/types/reference';
+
+type InputReaction = Pick<Reaction, 'references'>;
+
+export const getReferencesWithoutEmptyLink = (
+  reaction: InputReaction | undefined,
+): ReferenceFiltered[] =>
+  (reaction?.references || []).filter(
+    (ref): ref is ReferenceFiltered => ref.link !== null && ref.link !== undefined,
+  );
diff --git a/src/redux/reactions/utils/getGroupedReferences.test.ts b/src/redux/reactions/utils/getGroupedReferences.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..65359741f252355813570b0072b15b268f3a28f8
--- /dev/null
+++ b/src/redux/reactions/utils/getGroupedReferences.test.ts
@@ -0,0 +1,89 @@
+import { ReferenceFiltered } from '@/types/reference';
+import { getReferencesGroupedBySource } from './getGroupedReferences';
+
+describe('getGroupedReferences - util', () => {
+  const singleReference = {
+    link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+    article: {
+      title:
+        'The nutrient-responsive transcription factor TFE3 promotes autophagy, lysosomal biogenesis, and clearance of cellular debris.',
+      authors: [
+        'Martina JA',
+        ' Diab HI',
+        ' Lishu L',
+        ' Jeong-A L',
+        ' Patange S',
+        ' Raben N',
+        ' Puertollano R.',
+      ],
+      journal: 'Science signaling',
+      year: 2014,
+      link: 'https://www.ncbi.nlm.nih.gov/pubmed/24448649',
+      pubmedId: '24448649',
+      citationCount: 321,
+    },
+    type: 'PUBMED',
+    resource: '24448649',
+    id: 154973,
+    annotatorClassName: '',
+  };
+
+  const cases = [
+    [[], []],
+    [
+      [singleReference],
+      [
+        {
+          source: '',
+          references: [singleReference],
+        },
+      ],
+    ],
+    [
+      [
+        {
+          ...singleReference,
+          annotatorClassName: 'source1',
+        },
+        {
+          ...singleReference,
+          annotatorClassName: 'source1',
+        },
+        {
+          ...singleReference,
+          annotatorClassName: 'source2',
+        },
+      ],
+      [
+        {
+          source: 'source1',
+          references: [
+            {
+              ...singleReference,
+              annotatorClassName: 'source1',
+            },
+            {
+              ...singleReference,
+              annotatorClassName: 'source1',
+            },
+          ],
+        },
+        {
+          source: 'source2',
+          references: [
+            {
+              ...singleReference,
+              annotatorClassName: 'source2',
+            },
+          ],
+        },
+      ],
+    ],
+  ];
+
+  it.each(cases)('should return correct grouped references', (references, referencesGrouped) =>
+    expect(getReferencesGroupedBySource(references as ReferenceFiltered[])).toMatchObject(
+      referencesGrouped,
+    ),
+  );
+});
diff --git a/src/redux/reactions/utils/getGroupedReferences.ts b/src/redux/reactions/utils/getGroupedReferences.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ca09f0a93e4357e4a594c055a7d27ce38f58718c
--- /dev/null
+++ b/src/redux/reactions/utils/getGroupedReferences.ts
@@ -0,0 +1,11 @@
+import { ReferenceFiltered, ReferenceGrouped } from '@/types/reference';
+import { groupBy } from '@/utils/array/groupBy';
+
+export const getReferencesGroupedBySource = (references: ReferenceFiltered[]): ReferenceGrouped => {
+  const referencesGroupedObject = groupBy(references, ref => ref.annotatorClassName);
+
+  return Object.entries(referencesGroupedObject).map(([source, refs]) => ({
+    source,
+    references: refs,
+  }));
+};
diff --git a/src/shared/DrawerHeading/DrawerHeading.component.tsx b/src/shared/DrawerHeading/DrawerHeading.component.tsx
index 650c76f3941101f182cd3e941e51328134a3da6d..17f616ad625f8a70e781cf037e3a2ddb38d2cd7e 100644
--- a/src/shared/DrawerHeading/DrawerHeading.component.tsx
+++ b/src/shared/DrawerHeading/DrawerHeading.component.tsx
@@ -1,10 +1,10 @@
+import { closeDrawer } from '@/redux/drawer/drawer.slice';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { IconButton } from '@/shared/IconButton';
-import { closeDrawer } from '@/redux/drawer/drawer.slice';
 import { CLOSE_BUTTON_ROLE } from '../DrawerHeadingBackwardButton/DrawerHeadingBackwardButton.constants';
 
 interface DrawerHeadingProps {
-  title: string;
+  title: string | React.ReactNode;
 }
 
 export const DrawerHeading = ({ title }: DrawerHeadingProps): JSX.Element => {
diff --git a/src/types/drawerName.ts b/src/types/drawerName.ts
index 3dcb4bdce5c8ce8fbf6c6129956eaa23d55ab0f4..2f7938506e57bacf7160c83abce8d4886aeba945 100644
--- a/src/types/drawerName.ts
+++ b/src/types/drawerName.ts
@@ -5,4 +5,5 @@ export type DrawerName =
   | 'plugins'
   | 'export'
   | 'legend'
-  | 'submaps';
+  | 'submaps'
+  | 'reaction';
diff --git a/src/types/models.ts b/src/types/models.ts
index 27b6246e82c88f5b95e699fb154a5d3292bf3633..5b99701639f8f1a0cc8c6a728e8343117bbba951 100644
--- a/src/types/models.ts
+++ b/src/types/models.ts
@@ -14,6 +14,7 @@ import { overviewImageView } from '@/models/overviewImageView';
 import { projectSchema } from '@/models/project';
 import { reactionSchema } from '@/models/reaction';
 import { reactionLineSchema } from '@/models/reactionLineSchema';
+import { referenceSchema } from '@/models/referenceSchema';
 import { targetSchema } from '@/models/targetSchema';
 import { z } from 'zod';
 
@@ -32,6 +33,7 @@ export type BioEntityContent = z.infer<typeof bioEntityContentSchema>;
 export type BioEntityResponse = z.infer<typeof bioEntityResponseSchema>;
 export type Chemical = z.infer<typeof chemicalSchema>;
 export type Reaction = z.infer<typeof reactionSchema>;
+export type Reference = z.infer<typeof referenceSchema>;
 export type ReactionLine = z.infer<typeof reactionLineSchema>;
 export type ElementSearchResult = z.infer<typeof elementSearchResult>;
 export type ElementSearchResultType = z.infer<typeof elementSearchResultType>;
diff --git a/src/types/reference.ts b/src/types/reference.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e7201433a7a6ea9d609b35a094c4a6e0b3eea309
--- /dev/null
+++ b/src/types/reference.ts
@@ -0,0 +1,10 @@
+import { Reference } from './models';
+
+export type ReferenceFiltered = Omit<Reference, 'link'> & { link: string };
+
+export type ReferenceGroup = {
+  references: ReferenceFiltered[];
+  source: string;
+};
+
+export type ReferenceGrouped = ReferenceGroup[];
diff --git a/src/utils/array/groupBy.test.ts b/src/utils/array/groupBy.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..32bbc32a61821ddccb5b74b2e00d5316bb9c2dfe
--- /dev/null
+++ b/src/utils/array/groupBy.test.ts
@@ -0,0 +1,85 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { groupBy } from './groupBy';
+
+interface InputObject {
+  title: string;
+  value: number;
+}
+
+describe('groupBy - util', () => {
+  const cases: [InputObject[], (value: InputObject) => string, { [key: string]: InputObject[] }][] =
+    [
+      [
+        [
+          {
+            title: 'GROUP_1',
+            value: 1,
+          },
+          {
+            title: 'GROUP_1',
+            value: 2,
+          },
+          {
+            title: 'GROUP_1',
+            value: 3,
+          },
+          {
+            title: 'GROUP_2',
+            value: 1,
+          },
+          {
+            title: 'GROUP_3',
+            value: 1,
+          },
+        ],
+        (obj): string => obj.title,
+        {
+          GROUP_1: [
+            { title: 'GROUP_1', value: 1 },
+            { title: 'GROUP_1', value: 2 },
+            { title: 'GROUP_1', value: 3 },
+          ],
+          GROUP_2: [{ title: 'GROUP_2', value: 1 }],
+          GROUP_3: [{ title: 'GROUP_3', value: 1 }],
+        },
+      ],
+      [
+        [
+          {
+            title: '1',
+            value: 1,
+          },
+          {
+            title: '1',
+            value: 2,
+          },
+          {
+            title: '1',
+            value: 3,
+          },
+          {
+            title: '2',
+            value: 1,
+          },
+          {
+            title: '3',
+            value: 1,
+          },
+        ],
+        (obj): string => obj.value.toString(),
+        {
+          '1': [
+            { title: '1', value: 1 },
+            { title: '2', value: 1 },
+            { title: '3', value: 1 },
+          ],
+          '2': [{ title: '1', value: 2 }],
+          '3': [{ title: '1', value: 3 }],
+        },
+      ],
+    ];
+
+  it.each(cases)('should return valid data basing on predicate', (input, predicate, output) => {
+    expect(groupBy(input as any[], predicate)).toStrictEqual(output);
+  });
+});
diff --git a/src/utils/array/groupBy.ts b/src/utils/array/groupBy.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4fe4d030639d4a5b02233518efbab87db527e2af
--- /dev/null
+++ b/src/utils/array/groupBy.ts
@@ -0,0 +1,12 @@
+/* prettier-ignore */
+export const groupBy = <T>(
+  array: T[],
+  predicate: (value: T, index: number, arr: T[]) => string,
+): { [key: string]: T[] } =>
+    array.reduce(
+      (acc, value, index, arr) => {
+        (acc[predicate(value, index, arr)] ||= []).push(value);
+        return acc;
+      },
+    {} as { [key: string]: T[] },
+    );