diff --git a/src/web/assets/help.js b/src/web/assets/404.js
similarity index 73%
rename from src/web/assets/help.js
rename to src/web/assets/404.js
index 475c506789..46fd004f14 100644
--- a/src/web/assets/help.js
+++ b/src/web/assets/404.js
@@ -2,6 +2,13 @@ const yn = window.confirm(
 	'サーバー上に存在しないスクリプトがリクエストされました。お使いのMisskeyのバージョンが古いことが原因の可能性があります。Misskeyを更新しますか?');
 
 if (yn) {
+	// Clear cache (serive worker)
+	try {
+		navigator.serviceWorker.controller.postMessage('clear');
+	} catch (e) {
+		console.error(e);
+	}
+
 	location.reload(true);
 } else {
 	alert('問題が解決しない場合はサーバー管理者までお問い合せください。');
diff --git a/src/web/assets/recover.html b/src/web/assets/recover.html
new file mode 100644
index 0000000000..8042d438c4
--- /dev/null
+++ b/src/web/assets/recover.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>Misskeyのリカバリ</title>
+		<script>
+
+			const yn = window.confirm('キャッシュをクリアしますか?\y\yDo you want to clear caches?');
+
+			if (yn) {
+				try {
+					navigator.serviceWorker.controller.postMessage('clear');
+
+					navigator.serviceWorker.getRegistrations().then(registrations => {
+						registrations.forEach(registration => registration.unregister());
+					});
+
+				} catch (e) {
+					console.error(e);
+				}
+
+				localStorage.setItem('should-refresh', 'true');
+
+				alert('キャッシュをクリアしました。');
+			} else {
+				alert('問題が解決しない場合はサーバー管理者までお問い合せください。');
+			}
+
+		</script>
+	</head>
+</html>
diff --git a/src/web/server.ts b/src/web/server.ts
index 791b75ce09..1d3687f89e 100644
--- a/src/web/server.ts
+++ b/src/web/server.ts
@@ -39,11 +39,13 @@ app.get('/apple-touch-icon.png', (req, res) => res.sendFile(`${__dirname}/assets
 app.use('/assets', express.static(`${__dirname}/assets`, {
 	maxAge: ms('7 days')
 }));
-app.use('/assets/*.js', (req, res) => res.sendFile(`${__dirname}/assets/help.js`));
+app.use('/assets/*.js', (req, res) => res.sendFile(`${__dirname}/assets/404.js`));
 app.use('/assets', (req, res) => {
 	res.sendStatus(404);
 });
 
+app.use('/recover', (req, res) => res.sendFile(`${__dirname}/assets/recover.html`));
+
 /**
  * ServiceWroker
  */