diff --git a/apps/weather_status/appinfo/routes.php b/apps/weather_status/appinfo/routes.php
index 6218595a3813c7f1c2f471a8f8d8ee98f0cede8f..8737bfd2dc6c05a1d4079a9fff1e442230460883 100644
--- a/apps/weather_status/appinfo/routes.php
+++ b/apps/weather_status/appinfo/routes.php
@@ -30,5 +30,7 @@ return [
 		['name' => 'WeatherStatus#getLocation', 'url' => '/api/v1/location', 'verb' => 'GET'],
 		['name' => 'WeatherStatus#setLocation', 'url' => '/api/v1/location', 'verb' => 'PUT'],
 		['name' => 'WeatherStatus#getForecast', 'url' => '/api/v1/forecast', 'verb' => 'GET'],
+		['name' => 'WeatherStatus#getFavorites', 'url' => '/api/v1/favorites', 'verb' => 'GET'],
+		['name' => 'WeatherStatus#setFavorites', 'url' => '/api/v1/favorites', 'verb' => 'PUT'],
 	],
 ];
diff --git a/apps/weather_status/js/weather-status.js b/apps/weather_status/js/weather-status.js
index 79699909614a3207e0f5bd062d9e0e927fe5db60..228fd92262f2b310bd0143f370b19bbac211ed75 100644
Binary files a/apps/weather_status/js/weather-status.js and b/apps/weather_status/js/weather-status.js differ
diff --git a/apps/weather_status/js/weather-status.js.map b/apps/weather_status/js/weather-status.js.map
index 104bb806b6d5020a24fe512e3cf217808bcded06..e8fd067b525d3cd07ca5a746dd1c23914f63ceec 100644
Binary files a/apps/weather_status/js/weather-status.js.map and b/apps/weather_status/js/weather-status.js.map differ
diff --git a/apps/weather_status/lib/Controller/WeatherStatusController.php b/apps/weather_status/lib/Controller/WeatherStatusController.php
index 3813bbf9b41f1fe0f8af29613bb592b77229e0a7..7ec6c71493e6e088592175ef1c06b718e0278a41 100644
--- a/apps/weather_status/lib/Controller/WeatherStatusController.php
+++ b/apps/weather_status/lib/Controller/WeatherStatusController.php
@@ -121,4 +121,27 @@ class WeatherStatusController extends OCSController {
 			return new DataResponse($forecast);
 		}
 	}
+
+	/**
+	 * @NoAdminRequired
+	 *
+	 * Get favorites list
+	 *
+	 * @return DataResponse which contains the favorite list
+	 */
+	public function getFavorites(): DataResponse {
+		return new DataResponse($this->service->getFavorites());
+	}
+
+	/**
+	 * @NoAdminRequired
+	 *
+	 * Set favorites list
+	 *
+	 * @param array $favorites
+	 * @return DataResponse success state
+	 */
+	public function setFavorites(array $favorites): DataResponse {
+		return new DataResponse($this->service->setFavorites($favorites));
+	}
 }
diff --git a/apps/weather_status/lib/Service/WeatherStatusService.php b/apps/weather_status/lib/Service/WeatherStatusService.php
index 2d9140c321826bab7e1e3228c64d3d1578856da5..0d7b31f90429df0b8a98df1a2cc9beae9dcb283d 100644
--- a/apps/weather_status/lib/Service/WeatherStatusService.php
+++ b/apps/weather_status/lib/Service/WeatherStatusService.php
@@ -133,6 +133,26 @@ class WeatherStatusService {
 		return ['success' => true];
 	}
 
+	/**
+	 * Get favorites list
+	 * @param array $favorites
+	 * @return array success state
+	 */
+	public function getFavorites(): array {
+		$favoritesJson = $this->config->getUserValue($this->userId, Application::APP_ID, 'favorites', '');
+		return json_decode($favoritesJson, true) ?: [];
+	}
+
+	/**
+	 * Set favorites list
+	 * @param array $favorites
+	 * @return array success state
+	 */
+	public function setFavorites(array $favorites): array {
+		$this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites));
+		return ['success' => true];
+	}
+
 	/**
 	 * Try to use the address set in user personal settings as weather location
 	 *
diff --git a/apps/weather_status/src/App.vue b/apps/weather_status/src/App.vue
index e574bed1fb7a368dd5ba908b76c4bcd367129992..81edc28eaf458dc1bfd3ad9cf43ebf7ffc8812e9 100644
--- a/apps/weather_status/src/App.vue
+++ b/apps/weather_status/src/App.vue
@@ -26,13 +26,18 @@
 				class="weather-status-menu-item__subheader"
 				:default-icon="weatherIcon"
 				:menu-title="visibleMessage">
-				<ActionLink v-if="address && !errorMessage"
+				<ActionLink v-if="gotWeather"
 					icon="icon-address"
 					target="_blank"
 					:href="weatherLinkTarget"
 					:close-after-click="true">
 					{{ locationText }}
 				</ActionLink>
+				<ActionButton v-if="gotWeather"
+					:icon="addRemoveFavoriteIcon"
+					@click="onAddRemoveFavoriteClick">
+					{{ addRemoveFavoriteText }}
+				</ActionButton>
 				<ActionSeparator v-if="address && !errorMessage" />
 				<ActionButton
 					icon="icon-crosshair"
@@ -49,6 +54,18 @@
 					@submit="onAddressSubmit">
 					{{ t('weather_status', 'Set custom address') }}
 				</ActionInput>
+				<ActionButton
+					v-show="favorites.length > 0"
+					:icon="toggleFavoritesIcon"
+					@click="showFavorites = !showFavorites">
+					{{ t('weather_status', 'Favorites') }}
+				</ActionButton>
+				<ActionButton v-for="f in displayedFavorites"
+					:key="f"
+					icon="icon-starred"
+					@click="onFavoriteClick(f)">
+					{{ f }}
+				</ActionButton>
 			</Actions>
 		</div>
 	</li>
@@ -160,6 +177,8 @@ export default {
 			lon: null,
 			forecasts: [],
 			loop: null,
+			favorites: [],
+			showFavorites: false,
 		}
 	},
 	computed: {
@@ -217,6 +236,34 @@ export default {
 		weatherLinkTarget() {
 			return 'https://www.windy.com/-Rain-thunder-rain?rain,' + this.lat + ',' + this.lon + ',11'
 		},
+		gotWeather() {
+			return this.address && !this.errorMessage
+		},
+		addRemoveFavoriteIcon() {
+			return this.currentAddressIsFavorite
+				? 'icon-starred'
+				: 'icon-star'
+		},
+		addRemoveFavoriteText() {
+			return this.currentAddressIsFavorite
+				? t('weather_status', 'Remove from favorites')
+				: t('weather_status', 'Add as favorite')
+		},
+		currentAddressIsFavorite() {
+			return this.favorites.find((f) => {
+				return f === this.address
+			})
+		},
+		toggleFavoritesIcon() {
+			return this.showFavorites
+				? 'icon-triangle-s'
+				: 'icon-triangle-e'
+		},
+		displayedFavorites() {
+			return this.showFavorites
+				? this.favorites
+				: []
+		},
 	},
 	mounted() {
 		this.initWeatherStatus()
@@ -235,6 +282,8 @@ export default {
 				} else if (this.mode === MODE_MANUAL_LOCATION) {
 					this.startLoop()
 				}
+				const favs = await network.getFavorites()
+				this.favorites = favs
 			} catch (err) {
 				if (err?.code === 'ECONNABORTED') {
 					console.info('The weather status request was cancelled because the user navigates.')
@@ -378,6 +427,23 @@ export default {
 				? ((celcius * (9 / 5)) + 32).toFixed(1)
 				: celcius
 		},
+		onAddRemoveFavoriteClick() {
+			const currentIsFavorite = this.currentAddressIsFavorite
+			if (currentIsFavorite) {
+				const i = this.favorites.indexOf(currentIsFavorite)
+				if (i !== -1) {
+					this.favorites.splice(i, 1)
+				}
+			} else {
+				this.favorites.push(this.address)
+			}
+			network.saveFavorites(this.favorites)
+		},
+		onFavoriteClick(favAddress) {
+			if (favAddress !== this.address) {
+				this.setAddress(favAddress)
+			}
+		},
 	},
 }
 </script>
diff --git a/apps/weather_status/src/services/weatherStatusService.js b/apps/weather_status/src/services/weatherStatusService.js
index 54ea13259ae0c616c5695ea4c3a77d9d6540bbd7..32a81bd61087d0ca452141ab7c6bb6f2e85bd455 100644
--- a/apps/weather_status/src/services/weatherStatusService.js
+++ b/apps/weather_status/src/services/weatherStatusService.js
@@ -106,6 +106,33 @@ const fetchForecast = async() => {
 	return response.data.ocs.data
 }
 
+/**
+ * Fetches the location favorites
+ *
+ * @param {String} address The location
+ * @returns {Promise<Object>}
+ */
+const getFavorites = async() => {
+	const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'favorites'
+	const response = await HttpClient.get(url)
+
+	return response.data.ocs.data
+}
+
+/**
+ *
+ * @param {Array} favorites List of favorite addresses
+ * @returns {Promise<Object>}
+ */
+const saveFavorites = async(favorites) => {
+	const url = generateOcsUrl('apps/weather_status/api/v1', 2) + 'favorites'
+	const response = await HttpClient.put(url, {
+		favorites,
+	})
+
+	return response.data.ocs.data
+}
+
 export {
 	usePersonalAddress,
 	setMode,
@@ -113,4 +140,6 @@ export {
 	setLocation,
 	setAddress,
 	fetchForecast,
+	getFavorites,
+	saveFavorites,
 }