diff --git a/Classes/Controller/YoutubeController.php b/Classes/Controller/YoutubeController.php
index 4bc127b34503de6b7d4b5a61f5e589a72e7de7b1..0f4faa88aa2271e46fff3486678dc51cbce5156a 100644
--- a/Classes/Controller/YoutubeController.php
+++ b/Classes/Controller/YoutubeController.php
@@ -65,7 +65,7 @@ class YoutubeController extends ActionController {
 			}
 
 			$jsonArray['items'] = $this->youtubeService->mapArray(
-				$jsonArray['items'], $id, $aspectRatio, $thumbnailType
+				$jsonArray['items'], $id, $aspectRatio, $thumbnailType, $apiKey
 			);
 
 		} catch (Exception $exception) {
diff --git a/Classes/Service/YoutubeService.php b/Classes/Service/YoutubeService.php
index 4a214501159ac8e9eaa6c4b0f00cba0298b635ed..e44da64d1056b1ae5f851a69d4e31238b06989bb 100644
--- a/Classes/Service/YoutubeService.php
+++ b/Classes/Service/YoutubeService.php
@@ -2,8 +2,6 @@
 
 namespace SGalinski\SgYoutube\Service;
 
-use InvalidArgumentException;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -28,6 +26,16 @@ use InvalidArgumentException;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use InvalidArgumentException;
+use TYPO3\CMS\Core\Context\Context;
+use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
+use TYPO3\CMS\Core\Context\LanguageAspect;
+use TYPO3\CMS\Core\Http\ServerRequest;
+use TYPO3\CMS\Core\Registry;
+use TYPO3\CMS\Core\Site\Entity\Site;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\VersionNumberUtility;
+
 /**
  * YouTube Helper Service
  */
@@ -37,6 +45,7 @@ class YoutubeService {
 	const API_PLAYLIST = 'playlistItems';
 	const API_VIDEO = 'videos';
 	const API_PART = 'snippet';
+	const API_PART_LOCALIZATIONS = 'localizations';
 	const API_ORDER_BY = 'date';
 
 	/**
@@ -47,11 +56,26 @@ class YoutubeService {
 	 * @param string $youtubeId
 	 * @param string $aspectRatio 16:9 (default) or 4:3 (ONLY used if byAspectRation is set as thumbnail type)
 	 * @param string $thumbnailType maxres, standard, high, medium, default, byAspectRatio (default)
+	 * @param string $apiKey
 	 * @return array
 	 */
 	public function mapArray(
-		$jsonArray = [], $youtubeId = '', $aspectRatio = '16:9', $thumbnailType = 'byAspectRatio'
+		$jsonArray = [], $youtubeId = '', $aspectRatio = '16:9', $thumbnailType = 'byAspectRatio', $apiKey = ''
 	): array {
+		if (count($jsonArray) <= 0) {
+			return $jsonArray;
+		}
+
+		// Normalize the data to video details.
+		if (strpos($youtubeId, 'UC') === 0 || strpos($youtubeId, 'PL') === 0) {
+			$result = $this->getDetailedVideoInformationForJsonArray($jsonArray, $apiKey, self::API_PART);
+			if (count($result) <= 0 || !isset($result['items'])) {
+				return $jsonArray;
+			}
+
+			$jsonArray = $result['items'];
+		}
+
 		if (!in_array($thumbnailType, ['maxres', 'standard', 'high', 'medium', 'default', 'byAspectRatio'])) {
 			$thumbnailType = 'byAspectRatio';
 		}
@@ -60,22 +84,26 @@ class YoutubeService {
 			$aspectRatio = '16:9';
 		}
 
-		$result = [];
-		foreach ($jsonArray as $field) {
-			if (strpos($youtubeId, 'UC') === 0) {
-				$youTubeIdFromArray = $field['id']['videoId'];
+		// Localization is just available from TYPO3 9.X.X
+		if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '>=')) {
+			$context = GeneralUtility::makeInstance(Context::class);
 
-				// prevent the channel preview
-				if ($field['id']['kind'] !== 'youtube#video') {
-					continue;
-				}
+			try {
+				/** @var LanguageAspect $languageAspect */
+				$languageAspect = $context->getAspect('language');
+				$currentLanguageUid = $languageAspect->getId();
+			} catch (AspectNotFoundException $e) {
+				// Can't be possible to land here, otherwise the whole frontend would be weird as hell..
+				$currentLanguageUid = 0;
+			}
 
-			} elseif (strpos($youtubeId, 'PL') === 0) {
-				$youTubeIdFromArray = $field['snippet']['resourceId']['videoId'];
-			} else {
-				$youTubeIdFromArray = $field['id'];
+			if ($currentLanguageUid > 0 && $youtubeId && $apiKey) {
+				$jsonArray = $this->addLocalizationData($jsonArray, $apiKey, $currentLanguageUid);
 			}
+		}
 
+		$result = [];
+		foreach ($jsonArray as $field) {
 			$previewImage = [];
 			$resolutionTypes = ['maxres', 'standard', 'high', 'medium', 'default'];
 			if ($thumbnailType !== 'byAspectRatio') {
@@ -105,23 +133,163 @@ class YoutubeService {
 				'title' => $field['snippet']['title'],
 				'description' => strip_tags($field['snippet']['description']),
 				'thumbnail' => $previewImage['url'],
-				'url' => 'https://www.youtube.com/watch?v=' . $youTubeIdFromArray
+				'url' => 'https://www.youtube.com/watch?v=' . $field['id']
 			];
 		}
 
 		return $result;
 	}
 
+	/**
+	 * Adds the localized title and description for each of the given entries in the jsonArray and returns it.
+	 *
+	 * @param array $jsonArray
+	 * @param string $apiKey
+	 * @param int $currentLanguageUid
+	 *
+	 * @return array
+	 */
+	protected function addLocalizationData(array $jsonArray, $apiKey, $currentLanguageUid): array {
+		if (!$apiKey || !$currentLanguageUid || count($jsonArray) <= 0) {
+			return $jsonArray;
+		}
+
+		$localizationData = $this->getDetailedVideoInformationForJsonArray(
+			$jsonArray, $apiKey, self::API_PART_LOCALIZATIONS
+		);
+		if (!isset($localizationData['items']) || count($localizationData['items']) <= 0) {
+			return $jsonArray;
+		}
+
+		/** @var ServerRequest $request */
+		$request = $GLOBALS['TYPO3_REQUEST'];
+		$attributes = $request->getAttributes();
+		if (!isset($attributes['site'])) {
+			return $jsonArray;
+		}
+
+		/** @var Site $site */
+		$site = $attributes['site'];
+		$languages = $site->getLanguages();
+		$currentSiteLanguage = $languages[$currentLanguageUid];
+		if (!$currentSiteLanguage) {
+			return $jsonArray;
+		}
+
+		$languageIsoCodes = [
+			$currentSiteLanguage->getTwoLetterIsoCode()
+		];
+		foreach ($currentSiteLanguage->getFallbackLanguageIds() as $languageId) {
+			$siteLanguage = $languages[$languageId];
+			if (!$siteLanguage) {
+				continue;
+			}
+
+			$languageIsoCodes[] = $siteLanguage->getTwoLetterIsoCode();
+		}
+
+		foreach ($localizationData['items'] as $index => $localizationEntry) {
+			if (!isset($localizationEntry['localizations']) || count($localizationEntry['localizations']) <= 0) {
+				continue;
+			}
+
+			$title = '';
+			$description = '';
+			$localizations = $localizationEntry['localizations'];
+			foreach ($languageIsoCodes as $languageIsoCode) {
+				if ($title && $description) {
+					break;
+				}
+
+				if (!$title &&  isset($localizations[$languageIsoCode]['title'])) {
+					$title = $localizations[$languageIsoCode]['title'];
+				}
+
+				if (!$description &&  isset($localizations[$languageIsoCode]['description'])) {
+					$description = $localizations[$languageIsoCode]['description'];
+				}
+			}
+
+			if ($title) {
+				$jsonArray[$index]['snippet']['title'] = $title;
+			}
+
+			if ($description) {
+				$jsonArray[$index]['snippet']['description'] = $description;
+			}
+		}
+
+		return $jsonArray;
+	}
+
+	/**
+	 * Returns the detailed video information for the given json array and returns them as an array.
+	 *
+	 * @param array $jsonArray
+	 * @param string $apiKey
+	 * @param string $part
+	 *
+	 * @return array
+	 */
+	public function getDetailedVideoInformationForJsonArray(array $jsonArray, $apiKey, $part): array {
+		if (!$apiKey || count($jsonArray) <= 0) {
+			return $jsonArray;
+		}
+
+		$apiUrl = self::API_URL . self::API_VIDEO;
+		$parameters = [];
+		$parameters['part'] = $part;
+		$parameters['key'] = $apiKey;
+		$query = http_build_query($parameters);
+		foreach ($jsonArray as $videoData) {
+			$videoId = 0;
+			if (isset($videoData['id'])) {
+				$videoId = $videoData['id']['videoId'] ?? $videoData['id'];
+			}
+
+			if (!$videoId) {
+				continue;
+			}
+
+			$query .= '&id=' . $videoId;
+		}
+
+		$result = $this->getJsonAsArray('', '10', $apiKey, $apiUrl . '?' . $query);
+		if (!isset($result['items']) || count($result['items']) <= 0) {
+			return $jsonArray;
+		}
+
+		return $result;
+	}
+
 	/**
 	 * Returns a JSON array with the video details (title, description, preview image, url)
 	 *
 	 * @param string $youtubeId
 	 * @param string $maxResults
 	 * @param string $apiKey
+	 * @param string $url
 	 * @return array|mixed
 	 */
-	public function getJsonAsArray($youtubeId = '', $maxResults = '10', $apiKey = '') {
-		$url = $this->getApiUrl($youtubeId, $maxResults, $apiKey);
+	public function getJsonAsArray($youtubeId = '', $maxResults = '10', $apiKey = '', $url = '') {
+		if (!$url) {
+			$url = $this->getApiUrl($youtubeId, $maxResults, $apiKey);
+		}
+
+		$registry = GeneralUtility::makeInstance(Registry::class);
+		$currentDay = date('Y-m-d', $GLOBALS['EXEC_TIME']);
+		$cacheKey = sha1($url);
+		$disableYoutubeCache = (bool) GeneralUtility::_GP('disableYoutubeCache');
+		if (!$disableYoutubeCache) {
+			$cachedResult = $registry->get('sg_youtube', $cacheKey);
+			if ($cachedResult) {
+				if ($cachedResult['CACHE_DATE'] === $currentDay) {
+					return $cachedResult;
+				}
+
+				$registry->remove('sg_youtube', $cacheKey);
+			}
+		}
 
 		if (function_exists('curl_init')) {
 			$ch = curl_init();
@@ -164,6 +332,11 @@ class YoutubeService {
 			throw new InvalidArgumentException('No items found.', 403);
 		}
 
+		if (!$disableYoutubeCache) {
+			$jsonArray['CACHE_DATE'] = $currentDay;
+			$registry->set('sg_youtube', $cacheKey, $jsonArray);
+		}
+
 		return $jsonArray;
 	}
 
diff --git a/README.md b/README.md
index ff266c44fd9b42d023d321bad061d529413744e9..24e870cd25a0e75757f4a89c281c068cba5c5c1e 100644
--- a/README.md
+++ b/README.md
@@ -27,3 +27,33 @@ plugin.tx_sgyoutube {
 	}
 }
 ```
+
+### Registration for more than the free 10.000 quotas per day
+
+It's not 1 quota per 1 api call. Each api has it's own costs, which can be seen in the link below.
+
+Currently at the version 3.2.1 we are using the following apis:
+- "search/list" for channel videos
+- "playlistItems/list" for videos from a specific playlist
+- "videos/list" for getting the details for each video and the localizations, if needed.
+
+The maximum quota costs would be "102" at the moment for rendering the latest videos from a channel with the video 
+details and translations.
+
+[Quota Calculator](https://developers.google.com/youtube/v3/determine_quota_cost)
+
+[YouTube API Services - Audit and Quota Extension Form](https://support.google.com/youtube/contact/yt_api_form?hl=en)
+
+#### Caching behaviour
+
+Because of the quota costs we implemented a caching for the calls for each day. The response from the apis will be
+saved and used for 24 hours. Normally the site cache would do it, but it could be, that the cache will be cleared
+multiple times in a row, or that the plugin is on an uncached page. The TYPO3 registry is used as a cache. The cleanup
+will is handled on the fly.
+
+If the "?disableYoutubeCache=1" parameter is added to the url, this cache will be ignored as well.
+
+#### Possible way to solve the quota limit, if it's still reached
+
+You can use a different api-key for specific sites. You can implement a TypoScript page uid check and just change the
+key from the "TypoScript integration" topic.