diff --git a/Classes/Event/Listener/AccessPageListEventListener.php b/Classes/Event/Listener/AccessPageListEventListener.php
new file mode 100644
index 0000000000000000000000000000000000000000..9fcd678e9157be05ae6489ab89fe2cdaf8d2544a
--- /dev/null
+++ b/Classes/Event/Listener/AccessPageListEventListener.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace SGalinski\SgJobs\Event\Listener;
+
+use SGalinski\SgJobs\Service\SitemapService;
+use SGalinski\SgSeo\Events\AccessPageListEvent;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
+
+/**
+ * Class AccessPageListEventListener
+ *
+ * @package SGalinski\SgJobs\Event\Listener
+ */
+class AccessPageListEventListener {
+	/**
+	 * @var SitemapService
+	 */
+	protected $sitemapService;
+
+	/**
+	 * AccessPageListEventListener constructor.
+	 *
+	 * @param SitemapService $sitemapService
+	 */
+	public function __construct(SitemapService $sitemapService) {
+		$this->sitemapService = $sitemapService;
+	}
+
+	/**
+	 * @param AccessPageListEvent $event
+	 */
+	public function __invoke(AccessPageListEvent $event) {
+		$pageList = $event->getPageList();
+		$additionalPageList = $this->sitemapService->generatePagesList($event->getSysLanguageUid());
+		ArrayUtility::mergeRecursiveWithOverrule($pageList, $additionalPageList);
+		$event->setPageList($pageList);
+	}
+}
diff --git a/Classes/Service/SitemapService.php b/Classes/Service/SitemapService.php
new file mode 100644
index 0000000000000000000000000000000000000000..b71962b74af8e5c18e298c3658e64f9dd04f9361
--- /dev/null
+++ b/Classes/Service/SitemapService.php
@@ -0,0 +1,132 @@
+<?php
+
+namespace SGalinski\SgJobs\Service;
+
+use TYPO3\CMS\Core\Database\Connection;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Domain\Repository\PageRepository;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\Languagevisibility\Exception\TableNotSupportedException;
+use TYPO3\Languagevisibility\Service\FrontendServices;
+
+/**
+ * Class SitemapService
+ *
+ * @package SGalinski\SgJobs\Service
+ */
+class SitemapService {
+	/**
+	 * The plugin name
+	 */
+	public const PLUGIN_NAME = 'sgjobs_jobapplication';
+
+	/**
+	 * Generate a pageList array for the sitemap generation
+	 *
+	 * @param int $sysLanguageUid
+	 * @return array
+	 */
+	public function generatePagesList(int $sysLanguageUid): array {
+		$pageList = [];
+		// find sites where job detail plugin is added
+		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+			->getQueryBuilderForTable('tt_content');
+		$databaseResource = $queryBuilder->select('pid', 'pages')
+			->from('tt_content')
+			->where(
+				$queryBuilder->expr()->andX(
+					$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')),
+					$queryBuilder->expr()->eq(
+						'list_type',
+						$queryBuilder->createNamedParameter(self::PLUGIN_NAME)
+					),
+					$queryBuilder->expr()->orX(
+						$queryBuilder->expr()->eq('sys_language_uid', -1),
+						$queryBuilder->expr()->eq(
+							'sys_language_uid',
+							$queryBuilder->createNamedParameter($sysLanguageUid, Connection::PARAM_INT)
+						)
+					)
+				)
+			)
+			->execute();
+
+		$rows = $databaseResource->fetchAll();
+		foreach ($rows as $row) {
+			$jobs = $this->getJobsByPid($row['pages'], $sysLanguageUid);
+
+			foreach ($jobs as $job) {
+				$url = $GLOBALS['TSFE']->cObj->typoLink_URL(
+					[
+						'parameter' => $row['pid'],
+						'linkAccessRestrictedPages' => 1,
+						'forceAbsoluteUrl' => 1,
+						'additionalParams' => GeneralUtility::implodeArrayForUrl(
+							NULL, ['tx_sgjobs_jobapplication[jobId]' => $job['uid']]
+						),
+					]
+				);
+
+				$pageList[] = [
+					'url' => htmlspecialchars($url),
+					'title' => ''
+				];
+			}
+		}
+		return $pageList;
+	}
+
+	/**
+	 * Get all jobs stored on specific page ids
+	 *
+	 * @param string $pageList
+	 * @param int $sysLanguageUid
+	 * @return array|null
+	 */
+	private function getJobsByPid(string $pageList, int $sysLanguageUid): ?array {
+		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+			->getQueryBuilderForTable('tx_sgjobs_domain_model_job');
+		$databaseResource = $queryBuilder->select('*')
+			->from('tx_sgjobs_domain_model_job')
+			->where(
+				$queryBuilder->expr()->andX(
+					$queryBuilder->expr()->in('pid', $queryBuilder->createNamedParameter($pageList)),
+					$queryBuilder->expr()->in('sys_language_uid', '-1,0')
+				)
+			)
+			->execute();
+
+		$visibleRows = [];
+		$rows = $databaseResource->fetchAll();
+		$pageRepository = GeneralUtility::makeInstance(PageRepository::class);
+		$isLanguageVisibilityLoaded = ExtensionManagementUtility::isLoaded('languagevisibility');
+		foreach ($rows as $row) {
+			$table = 'tx_sgjobs_domain_model_job';
+
+			// get languagevisibility uid that is available (check for the correct uid to fall back to)
+			if ($isLanguageVisibilityLoaded) {
+				try {
+					$element = FrontendServices::getElement($row, $table);
+				} catch(TableNotSupportedException $exception) {
+					continue;
+				}
+
+				$languageId = FrontendServices::getOverlayLanguageIdForElement($element, $sysLanguageUid);
+				if ($languageId === FALSE) {
+					continue;
+				}
+			} else {
+				$languageId = $sysLanguageUid;
+			}
+
+			if ($languageId > 0) {
+				$row = $pageRepository->getRecordOverlay($table, $row, $languageId);
+			}
+
+			$visibleRows[] = $row;
+		}
+
+		return $visibleRows;
+	}
+}
diff --git a/Classes/SignalSlot/SitemapSignalSlot.php b/Classes/SignalSlot/SitemapSignalSlot.php
index 205160410e1e17e039c7a09234a2c1fe075e79be..85f78f9badea396ea9fb4468f9a546f935a10652 100644
--- a/Classes/SignalSlot/SitemapSignalSlot.php
+++ b/Classes/SignalSlot/SitemapSignalSlot.php
@@ -26,18 +26,14 @@ namespace SGalinski\SgJobs\SignalSlot;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
-use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use SGalinski\SgJobs\Service\SitemapService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
-use \TYPO3\CMS\Core\Domain\Repository\PageRepository;
-use TYPO3\Languagevisibility\Service\FrontendServices;
 
 /**
  * Signal functions regarding sg_seo sitemap generation
  */
 class SitemapSignalSlot {
-	public const PLUGIN_NAME = 'sgjobs_jobapplication';
-
 	/**
 	 * Before the sitemap is generated
 	 *
@@ -46,100 +42,7 @@ class SitemapSignalSlot {
 	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
 	 */
 	public function beforeSitemapGeneration(array &$pageList, int $sysLanguageUid): void {
-		// find sites where job detail plugin is added
-		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-			->getQueryBuilderForTable('tt_content');
-		$databaseResource = $queryBuilder->select('pid', 'pages')
-			->from('tt_content')
-			->where(
-				$queryBuilder->expr()->andX(
-					$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')),
-					$queryBuilder->expr()->eq(
-						'list_type',
-						$queryBuilder->createNamedParameter(self::PLUGIN_NAME)
-					),
-					$queryBuilder->expr()->orX(
-						$queryBuilder->expr()->eq('sys_language_uid', -1),
-						$queryBuilder->expr()->eq(
-							'sys_language_uid',
-							$queryBuilder->createNamedParameter($sysLanguageUid, \PDO::PARAM_INT)
-						)
-					)
-				)
-			)
-			->execute();
-
-		$rows = $databaseResource->fetchAll();
-		foreach ($rows as $row) {
-			$jobs = $this->getJobsByPid($row['pages'], $sysLanguageUid);
-
-			foreach ($jobs as $job) {
-				$url = $GLOBALS['TSFE']->cObj->typoLink_URL(
-					[
-						'parameter' => $row['pid'],
-						'linkAccessRestrictedPages' => 1,
-						'forceAbsoluteUrl' => 1,
-						'additionalParams' => GeneralUtility::implodeArrayForUrl(
-							NULL, ['tx_sgjobs_jobapplication[jobId]' => $job['uid']]
-						),
-					]
-				);
-
-				$pageList[] = [
-					'url' => htmlspecialchars($url),
-					'title' => ''
-				];
-			}
-		}
-	}
-
-	/**
-	 * Get all jobs stored on specific page ids
-	 *
-	 * @param string $pageList
-	 * @param int $sysLanguageUid
-	 * @return array|null
-	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
-	 * @throws \Exception
-	 */
-	private function getJobsByPid(string $pageList, int $sysLanguageUid): ?array {
-		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-			->getQueryBuilderForTable('tx_sgjobs_domain_model_job');
-		$databaseResource = $queryBuilder->select('*')
-			->from('tx_sgjobs_domain_model_job')
-			->where(
-				$queryBuilder->expr()->andX(
-					$queryBuilder->expr()->in('pid', $queryBuilder->createNamedParameter($pageList)),
-					$queryBuilder->expr()->in('sys_language_uid', '-1,0')
-				)
-			)
-			->execute();
-
-		$visibleRows = [];
-		$rows = $databaseResource->fetchAll();
-		$pageRepository = GeneralUtility::makeInstance(PageRepository::class);
-		$isLanguageVisibilityLoaded = ExtensionManagementUtility::isLoaded('languagevisibility');
-		foreach ($rows as $row) {
-			$table = 'tx_sgjobs_domain_model_job';
-
-			// get languagevisibility uid that is available (check for the correct uid to fall back to)
-			if ($isLanguageVisibilityLoaded) {
-				$element = FrontendServices::getElement($row, $table);
-				$languageId = FrontendServices::getOverlayLanguageIdForElement($element, $sysLanguageUid);
-				if ($languageId === FALSE) {
-					continue;
-				}
-			} else {
-				$languageId = $sysLanguageUid;
-			}
-
-			if ($languageId > 0) {
-				$row = $pageRepository->getRecordOverlay($table, $row, $languageId);
-			}
-
-			$visibleRows[] = $row;
-		}
-
-		return $visibleRows;
+		$additionalPageList = GeneralUtility::makeInstance(SitemapService::class)->generatePagesList($sysLanguageUid);
+		ArrayUtility::mergeRecursiveWithOverrule($pageList, $additionalPageList);
 	}
 }
diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e3f92b2f882b5998aa6421e9945a610549196a54
--- /dev/null
+++ b/Configuration/Services.yaml
@@ -0,0 +1,6 @@
+services:
+  SGalinski\SgJobs\Event\Listener\AccessPageListEventListener:
+    tags:
+      - name: event.listener
+        identifier: 'accessPageListEvent'
+        event: SGalinski\SgSeo\Events\AccessPageListEvent
diff --git a/ext_localconf.php b/ext_localconf.php
index 20e78b8c9610e4c6226c8249df8564e30a540d59..f6f062c0739b563023f92a1826f827b4764ec98a 100644
--- a/ext_localconf.php
+++ b/ext_localconf.php
@@ -85,17 +85,19 @@ call_user_func(
 		// register mail templates
 		$GLOBALS['sg_mail'][$extKey]['ApplicationMail'] = 'EXT:' . $extKey . '/Configuration/SgMail/ApplicationMail.php';
 
-		// signal slot for sg_seo integration
-		/** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
-		$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
-			\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class
-		);
-		$signalSlotDispatcher->connect(
-			\SGalinski\SgSeo\Generator\PagesSitemapGenerator::class,
-			'accessPageList',
-			\SGalinski\SgJobs\SignalSlot\SitemapSignalSlot::class,
-			'beforeSitemapGeneration'
-		);
+		if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '10.4.0', '<')) {
+			// signal slot for sg_seo integration
+			/** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
+			$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
+				\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class
+			);
+			$signalSlotDispatcher->connect(
+				\SGalinski\SgSeo\Generator\PagesSitemapGenerator::class,
+				'accessPageList',
+				\SGalinski\SgJobs\SignalSlot\SitemapSignalSlot::class,
+				'beforeSitemapGeneration'
+			);
+		}
 
 		// Register the upgrade wizard
 		$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][\SGalinski\SgJobs\Updates\DepartmentUpdateWizard::IDENTIFIER]