diff --git a/Classes/Domain/Model/News.php b/Classes/Domain/Model/News.php
index bb9b2df7b38e8e27d713819b17714712fa5f92b1..d042f4b004717147ad9e35f700652254dc8786b1 100644
--- a/Classes/Domain/Model/News.php
+++ b/Classes/Domain/Model/News.php
@@ -107,9 +107,9 @@ class News extends CategoryAndNews {
 	 */
 	public function __construct() {
 		parent::__construct();
-		$this->relatedNews = new ObjectStorage();
 		$this->tags = new ObjectStorage();
 		$this->newsAuthor = new ObjectStorage();
+		$this->relatedNews = new ObjectStorage();
 	}
 
 	/**
diff --git a/Classes/Domain/Repository/NewsRepository.php b/Classes/Domain/Repository/NewsRepository.php
index 7bf40bf35b5b468295d6c7b1c19d391b39681284..c854896fb78dd5fd95c879354ff043a993101740 100644
--- a/Classes/Domain/Repository/NewsRepository.php
+++ b/Classes/Domain/Repository/NewsRepository.php
@@ -26,8 +26,10 @@ namespace SGalinski\SgNews\Domain\Repository;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
-use SGalinski\SgNews\Domain\Model\Author;
 use SGalinski\SgNews\Domain\Model\News;
+use TYPO3\CMS\Core\Database\Connection;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult;
 use TYPO3\CMS\Extbase\Persistence\QueryInterface;
 use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
@@ -505,4 +507,97 @@ class NewsRepository extends AbstractRepository {
 		$query->matching($query->equals('uid', $uid));
 		return $query->execute()->getFirst();
 	}
+
+	/**
+	 * This method finds news related by Tag or Category to the given news record
+	 *
+	 * @param News $news The news to find related news to
+	 * @param int $limit Limit the amount of related news
+	 * @return QueryResultInterface
+	 */
+	public function findRelated(News $news, int $limit = 0) {
+		$connection = $this->getConnection();
+		$qb = $connection->createQueryBuilder();
+		// We need to build the constraint for the tags/categories
+		$constraints = [];
+		$tags = $news->getTags();
+		if ($tags->count() > 0) {
+			$tagConstraints = [];
+			foreach ($tags as $tag) {
+				$qb->leftJoin('pages', 'sys_category_records_mm', 'tags', 'pages.uid=tags.uid_foreign');
+				$tagConstraints[] = $qb->expr()->eq('tags.uid_local', $tag->getUid());
+			}
+			$constraints[] = $qb->expr()->eq('tags.tablenames', $qb->createNamedParameter('pages'));
+			$constraints[] = $qb->expr()->eq('tags.fieldname', $qb->createNamedParameter('tx_sgnews_tags'));
+			$constraints[] = $qb->expr()->orX($tagConstraints);
+		} else {
+			$constraints[] = $qb->expr()->eq('pid', $news->getPid());
+		}
+
+		// here we fetch the lastUpdated of the $limit amount of news with newer lastUpdated dates
+		$result = $qb->select('lastUpdated')
+			->from('pages')
+			->where(
+				$qb->expr()->eq('doktype', $qb->createNamedParameter(News::DOK_TYPE_NEWS, Connection::PARAM_INT)),
+				$qb->expr()->gt('lastUpdated', $news->getLastUpdated()->getTimestamp()),
+				$qb->expr()->andX(...$constraints)
+			)
+			->setMaxResults($limit)
+			->orderBy('lastUpdated', 'desc')
+			->execute();
+		$newest = $result->fetchOne();
+
+		// Here we fetch the lastUpdated of the $limit amount of news with older lastUpdated dates
+		$result = $qb->select('lastUpdated')
+			->from('pages')
+			->where(
+				$qb->expr()->eq('doktype', $qb->createNamedParameter(News::DOK_TYPE_NEWS, Connection::PARAM_INT)),
+				$qb->expr()->lt('lastUpdated', $news->getLastUpdated()->getTimestamp()),
+				$qb->expr()->andX(...$constraints)
+			)
+			->setMaxResults($limit)
+			->orderBy('lastUpdated', 'asc')
+			->execute();
+		$oldest = $result->fetchOne();
+
+		$query = $this->createQuery();
+		$query->getQuerySettings()->setRespectStoragePage(FALSE);
+		$query->setOrderings([
+			'crdate' => QueryInterface::ORDER_DESCENDING
+		]);
+		$constraints = [];
+		if ($newest) {
+			$constraints[] = $query->lessThanOrEqual('lastUpdated', $newest);
+		}
+		if ($oldest) {
+			$constraints[] = $query->greaterThanOrEqual('lastUpdated', $oldest);
+		}
+
+		// Now we fetch the $limit amount of news via extbase query and limit them to the newest and oldest date
+		// remember, we fetched the oldest and newest date from the $limit amount of news newer and older then
+		// the given news. If we limit the result of the following query to $limit, we get $limit amount of news
+		// "around" the given news, where newer news are preferred due to the ordering.
+		$tags = $news->getTags();
+		if ($tags->count() > 0) {
+			foreach ($tags as $tag) {
+				$constraints[] = $query->contains('tags', $tag);
+			}
+		} else {
+			$constraints[] = $query->equals('pid', $news->getPid());
+		}
+
+		$query->matching(
+			$constraints
+		);
+		if ($limit > 0) {
+			$query->setLimit($limit);
+		}
+
+		return $query->execute();
+	}
+
+	protected function getConnection(): Connection {
+		return GeneralUtility::makeInstance(ConnectionPool::class)
+			->getConnectionForTable('pages');
+	}
 }
diff --git a/Classes/ViewHelpers/RelatedViewHelper.php b/Classes/ViewHelpers/RelatedViewHelper.php
new file mode 100644
index 0000000000000000000000000000000000000000..f49aeecbb0ba4c8109d328bceabf4588c9232f23
--- /dev/null
+++ b/Classes/ViewHelpers/RelatedViewHelper.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace SGalinski\SgNews\ViewHelpers;
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
+
+class RelatedViewHelper extends AbstractViewHelper {
+	/**
+	 * Initialize the view helper arguments
+	 */
+	public function initializeArguments() {
+		$this->registerArgument(
+			'news',
+			'SGalinski\SgNews\Domain\Model\News',
+			'The news record from which to find related news',
+			TRUE
+		);
+		$this->registerArgument('limit', 'int', 'Limit the amount of related news to display', FALSE, 5);
+		$this->registerArgument('as', 'string', 'The name of the iteration variable', TRUE);
+		$this->registerArgument('iteration', 'string', 'The name of the variable to store iteration information (index, cycle, isFirst, isLast, isEven, isOdd)');
+	}
+
+	/**
+	 * Render the ViewHelper
+	 * It works like the for-ViewHelper by running through the child content and adding the related news records to it
+	 *
+	 * @return string
+	 */
+	public function render() {
+		$news = $this->arguments['news'];
+		$newsRepository = GeneralUtility::makeInstance(NewsRepository::class);
+		$related = $newsRepository->findRelated($news);
+		$templateVariableContainer = $this->renderingContext->getVariableProvider();
+		$output = '';
+		if (isset($this->arguments['iteration'])) {
+            $iterationData = [
+                'index' => 0,
+                'cycle' => 1,
+                'total' => count($related)
+            ];
+        }
+		foreach ($related as $relatedNews) {
+			$templateVariableContainer->add($this->arguments['as'], $relatedNews);
+			if (isset($this->arguments['iteration'])) {
+                $iterationData['isFirst'] = $iterationData['cycle'] === 1;
+                $iterationData['isLast'] = $iterationData['cycle'] === $iterationData['total'];
+                $iterationData['isEven'] = $iterationData['cycle'] % 2 === 0;
+                $iterationData['isOdd'] = !$iterationData['isEven'];
+                $templateVariableContainer->add($this->arguments['iteration'], $iterationData);
+                $iterationData['index']++;
+                $iterationData['cycle']++;
+            }
+
+            $output .= $this->renderChildren();
+            $templateVariableContainer->remove($this->arguments['as']);
+			if (isset($this->arguments['iteration'])) {
+                $templateVariableContainer->remove($this->arguments['iteration']);
+            }
+		}
+
+		return $output;
+	}
+}
diff --git a/Resources/Private/Templates/SingleView/SingleView.html b/Resources/Private/Templates/SingleView/SingleView.html
index b9f098afd3e8a431d37aefe3ae39537627407321..ab6e7239814fa3c32bfc1b70b2a9ba16df61c955 100644
--- a/Resources/Private/Templates/SingleView/SingleView.html
+++ b/Resources/Private/Templates/SingleView/SingleView.html
@@ -179,21 +179,40 @@
 						</div>
 
 						<f:if condition="{newsMetaData.news.relatedNews}">
-							<div class="tx-sgnews-single-related">
-								<h3>
-									<f:translate key="frontend.singleview.relatedArticles" />
-								</h3>
-
-								<ul>
-									<f:for each="{newsMetaData.news.relatedNews}" as="relatedNewsEntry">
-										<li>
-											<a href="{f:uri.page(pageUid: '{relatedNewsEntry.uid}')}">
-												{relatedNewsEntry.subtitleWithFallbackToTitle}
-											</a>
-										</li>
-									</f:for>
-								</ul>
-							</div>
+							<f:then>
+								<div class="tx-sgnews-single-related">
+									<h3>
+										<f:translate key="frontend.singleview.relatedArticles" />
+									</h3>
+
+									<ul>
+										<f:for each="{newsMetaData.news.relatedNews}" as="relatedNewsEntry">
+											<li>
+												<a href="{f:uri.page(pageUid: '{relatedNewsEntry.uid}')}">
+													{relatedNewsEntry.subtitleWithFallbackToTitle}
+												</a>
+											</li>
+										</f:for>
+									</ul>
+								</div>
+							</f:then>
+							<f:else>
+								<div class="tx-sgnews-single-related">
+									<h3>
+										<f:translate key="frontend.singleview.relatedArticles" />
+									</h3>
+
+									<ul>
+										<sg:related news="{newsMetaData.news}" limit="5" as="relatedNewsEntry">
+											<li>
+												<a href="{f:uri.page(pageUid: '{relatedNewsEntry.uid}')}">
+													{relatedNewsEntry.subtitleWithFallbackToTitle}
+												</a>
+											</li>
+										</sg:related>
+									</ul>
+								</div>
+							</f:else>
 						</f:if>
 					</div>
 				</div>