From d8d4c4d2287489a02b3185a79ed0cac77057cf81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=93=E3=81=B4=E3=81=AA=E3=81=9F=E3=81=BF=E3=81=BD?=
 <syuilotan@yahoo.co.jp>
Date: Wed, 7 Feb 2018 18:47:29 +0900
Subject: [PATCH] wip

---
 src/web/app/auth/tags/form.tag                |  2 +-
 src/web/app/auth/tags/index.tag               |  2 +-
 src/web/app/ch/tags/channel.tag               | 10 +++++-----
 src/web/app/ch/tags/header.tag                |  2 +-
 src/web/app/ch/tags/index.tag                 |  2 +-
 src/web/app/common/tags/activity-table.tag    |  2 +-
 src/web/app/common/tags/authorized-apps.tag   |  2 +-
 src/web/app/common/tags/error.tag             |  4 ++--
 src/web/app/common/tags/file-type-icon.tag    |  2 +-
 src/web/app/common/tags/messaging/form.tag    |  2 +-
 src/web/app/common/tags/messaging/index.tag   |  2 +-
 src/web/app/common/tags/messaging/message.tag |  2 +-
 src/web/app/common/tags/messaging/room.tag    |  2 +-
 src/web/app/common/tags/nav-links.tag         |  2 +-
 src/web/app/common/tags/number.tag            |  2 +-
 src/web/app/common/tags/poll-editor.tag       |  2 +-
 src/web/app/common/tags/poll.tag              |  2 +-
 src/web/app/common/tags/post-menu.tag         |  2 +-
 src/web/app/common/tags/raw.tag               |  2 +-
 src/web/app/common/tags/reaction-picker.vue   |  2 +-
 src/web/app/common/tags/reactions-viewer.vue  |  2 +-
 src/web/app/common/tags/signin-history.tag    |  4 ++--
 src/web/app/common/tags/signin.tag            |  2 +-
 src/web/app/common/tags/signup.tag            |  2 +-
 src/web/app/common/tags/special-message.tag   |  2 +-
 src/web/app/common/tags/stream-indicator.vue  |  2 +-
 src/web/app/common/tags/time.vue              |  2 +-
 src/web/app/common/tags/twitter-setting.tag   |  2 +-
 src/web/app/common/tags/uploader.tag          |  2 +-
 src/web/app/desktop/tags/analog-clock.tag     |  2 +-
 .../desktop/tags/autocomplete-suggestion.tag  |  2 +-
 .../app/desktop/tags/big-follow-button.tag    |  2 +-
 src/web/app/desktop/tags/contextmenu.tag      |  2 +-
 src/web/app/desktop/tags/crop-window.tag      |  2 +-
 .../app/desktop/tags/detailed-post-window.tag |  2 +-
 src/web/app/desktop/tags/dialog.tag           |  2 +-
 src/web/app/desktop/tags/donation.tag         |  2 +-
 .../desktop/tags/drive/base-contextmenu.tag   |  2 +-
 .../app/desktop/tags/drive/browser-window.tag |  2 +-
 src/web/app/desktop/tags/drive/browser.tag    |  2 +-
 .../desktop/tags/drive/file-contextmenu.tag   |  2 +-
 src/web/app/desktop/tags/drive/file.tag       |  2 +-
 .../desktop/tags/drive/folder-contextmenu.tag |  2 +-
 src/web/app/desktop/tags/drive/folder.tag     |  2 +-
 src/web/app/desktop/tags/drive/nav-folder.tag |  2 +-
 src/web/app/desktop/tags/follow-button.tag    |  2 +-
 .../app/desktop/tags/following-setuper.tag    |  2 +-
 .../desktop/tags/home-widgets/access-log.tag  |  2 +-
 .../desktop/tags/home-widgets/activity.tag    |  2 +-
 .../desktop/tags/home-widgets/broadcast.tag   |  2 +-
 .../desktop/tags/home-widgets/calendar.tag    |  2 +-
 .../app/desktop/tags/home-widgets/channel.tag |  8 ++++----
 .../desktop/tags/home-widgets/donation.tag    |  2 +-
 .../desktop/tags/home-widgets/mentions.tag    |  2 +-
 .../desktop/tags/home-widgets/messaging.tag   |  2 +-
 src/web/app/desktop/tags/home-widgets/nav.tag |  2 +-
 .../tags/home-widgets/notifications.tag       |  2 +-
 .../tags/home-widgets/photo-stream.tag        |  2 +-
 .../desktop/tags/home-widgets/post-form.tag   |  2 +-
 .../app/desktop/tags/home-widgets/profile.tag |  2 +-
 .../tags/home-widgets/recommended-polls.tag   |  2 +-
 .../desktop/tags/home-widgets/rss-reader.tag  |  2 +-
 .../app/desktop/tags/home-widgets/server.tag  | 16 +++++++--------
 .../desktop/tags/home-widgets/slideshow.tag   |  2 +-
 .../desktop/tags/home-widgets/timeline.tag    |  2 +-
 .../desktop/tags/home-widgets/timemachine.tag |  2 +-
 .../app/desktop/tags/home-widgets/tips.tag    |  2 +-
 .../app/desktop/tags/home-widgets/trends.tag  |  2 +-
 .../tags/home-widgets/user-recommendation.tag |  2 +-
 .../app/desktop/tags/home-widgets/version.tag |  2 +-
 src/web/app/desktop/tags/home.tag             |  2 +-
 src/web/app/desktop/tags/images.tag           |  6 +++---
 src/web/app/desktop/tags/input-dialog.tag     |  2 +-
 src/web/app/desktop/tags/list-user.tag        |  2 +-
 .../desktop/tags/messaging/room-window.tag    |  2 +-
 src/web/app/desktop/tags/messaging/window.tag |  2 +-
 src/web/app/desktop/tags/notifications.tag    |  2 +-
 src/web/app/desktop/tags/pages/drive.tag      |  2 +-
 src/web/app/desktop/tags/pages/entrance.tag   |  4 ++--
 .../app/desktop/tags/pages/home-customize.tag |  2 +-
 src/web/app/desktop/tags/pages/home.tag       |  2 +-
 .../app/desktop/tags/pages/messaging-room.tag |  2 +-
 src/web/app/desktop/tags/pages/post.tag       |  2 +-
 src/web/app/desktop/tags/pages/search.tag     |  2 +-
 .../app/desktop/tags/pages/selectdrive.tag    |  2 +-
 src/web/app/desktop/tags/pages/user.tag       |  2 +-
 src/web/app/desktop/tags/post-detail-sub.tag  |  2 +-
 src/web/app/desktop/tags/post-detail.tag      |  2 +-
 src/web/app/desktop/tags/post-form-window.tag |  2 +-
 src/web/app/desktop/tags/post-form.tag        |  2 +-
 src/web/app/desktop/tags/post-preview.tag     |  2 +-
 src/web/app/desktop/tags/progress-dialog.tag  |  2 +-
 .../app/desktop/tags/repost-form-window.tag   |  2 +-
 src/web/app/desktop/tags/repost-form.tag      |  2 +-
 src/web/app/desktop/tags/search-posts.tag     |  2 +-
 src/web/app/desktop/tags/search.tag           |  2 +-
 .../tags/select-file-from-drive-window.tag    |  2 +-
 .../tags/select-folder-from-drive-window.tag  |  2 +-
 .../desktop/tags/set-avatar-suggestion.tag    |  2 +-
 .../desktop/tags/set-banner-suggestion.tag    |  2 +-
 src/web/app/desktop/tags/settings-window.tag  |  2 +-
 src/web/app/desktop/tags/settings.tag         | 14 ++++++-------
 src/web/app/desktop/tags/sub-post-content.tag |  2 +-
 src/web/app/desktop/tags/timeline.tag         |  6 +++---
 src/web/app/desktop/tags/ui.tag               | 18 ++++++++---------
 .../desktop/tags/user-followers-window.tag    |  2 +-
 src/web/app/desktop/tags/user-followers.tag   |  2 +-
 .../desktop/tags/user-following-window.tag    |  2 +-
 src/web/app/desktop/tags/user-following.tag   |  2 +-
 src/web/app/desktop/tags/user-preview.tag     |  2 +-
 src/web/app/desktop/tags/user-timeline.tag    |  2 +-
 src/web/app/desktop/tags/user.tag             | 18 ++++++++---------
 src/web/app/desktop/tags/users-list.tag       |  2 +-
 src/web/app/desktop/tags/widgets/activity.tag |  6 +++---
 src/web/app/desktop/tags/widgets/calendar.tag |  2 +-
 src/web/app/desktop/tags/window.tag           |  2 +-
 src/web/app/dev/tags/new-app-form.tag         |  2 +-
 src/web/app/dev/tags/pages/app.tag            |  2 +-
 src/web/app/dev/tags/pages/apps.tag           |  2 +-
 .../app/mobile/tags/drive-folder-selector.tag |  2 +-
 src/web/app/mobile/tags/drive-selector.tag    |  2 +-
 src/web/app/mobile/tags/drive.tag             |  2 +-
 src/web/app/mobile/tags/drive/file-viewer.tag |  2 +-
 src/web/app/mobile/tags/drive/file.tag        |  2 +-
 src/web/app/mobile/tags/drive/folder.tag      |  2 +-
 src/web/app/mobile/tags/follow-button.tag     |  2 +-
 src/web/app/mobile/tags/home-timeline.tag     |  2 +-
 src/web/app/mobile/tags/home.tag              |  2 +-
 src/web/app/mobile/tags/images.tag            |  4 ++--
 src/web/app/mobile/tags/init-following.tag    |  2 +-
 .../app/mobile/tags/notification-preview.tag  |  2 +-
 src/web/app/mobile/tags/notification.tag      |  2 +-
 src/web/app/mobile/tags/notifications.tag     |  2 +-
 src/web/app/mobile/tags/notify.tag            |  2 +-
 src/web/app/mobile/tags/page/drive.tag        |  2 +-
 src/web/app/mobile/tags/page/entrance.tag     |  2 +-
 src/web/app/mobile/tags/page/home.tag         |  2 +-
 .../app/mobile/tags/page/messaging-room.tag   |  2 +-
 src/web/app/mobile/tags/page/messaging.tag    |  2 +-
 .../app/mobile/tags/page/notifications.tag    |  2 +-
 src/web/app/mobile/tags/page/post.tag         |  2 +-
 src/web/app/mobile/tags/page/search.tag       |  2 +-
 src/web/app/mobile/tags/page/selectdrive.tag  |  2 +-
 src/web/app/mobile/tags/page/settings.tag     |  4 ++--
 .../tags/page/settings/authorized-apps.tag    |  2 +-
 .../app/mobile/tags/page/settings/profile.tag |  4 ++--
 .../app/mobile/tags/page/settings/signin.tag  |  2 +-
 .../app/mobile/tags/page/settings/twitter.tag |  2 +-
 .../app/mobile/tags/page/user-followers.tag   |  2 +-
 .../app/mobile/tags/page/user-following.tag   |  2 +-
 src/web/app/mobile/tags/page/user.tag         |  2 +-
 src/web/app/mobile/tags/post-detail.tag       |  4 ++--
 src/web/app/mobile/tags/post-form.tag         |  2 +-
 src/web/app/mobile/tags/post-preview.tag      |  2 +-
 src/web/app/mobile/tags/search-posts.tag      |  2 +-
 src/web/app/mobile/tags/search.tag            |  2 +-
 src/web/app/mobile/tags/sub-post-content.tag  |  2 +-
 src/web/app/mobile/tags/timeline.tag          |  6 +++---
 src/web/app/mobile/tags/ui.tag                |  6 +++---
 src/web/app/mobile/tags/user-card.tag         |  2 +-
 src/web/app/mobile/tags/user-followers.tag    |  2 +-
 src/web/app/mobile/tags/user-following.tag    |  2 +-
 src/web/app/mobile/tags/user-preview.tag      |  2 +-
 src/web/app/mobile/tags/user-timeline.tag     |  2 +-
 src/web/app/mobile/tags/user.tag              | 20 +++++++++----------
 src/web/app/mobile/tags/users-list.tag        |  2 +-
 src/web/app/stats/tags/index.tag              | 10 +++++-----
 src/web/app/status/tags/index.tag             |  8 ++++----
 168 files changed, 237 insertions(+), 237 deletions(-)

diff --git a/src/web/app/auth/tags/form.tag b/src/web/app/auth/tags/form.tag
index 8c085ee9b8..9b317fef46 100644
--- a/src/web/app/auth/tags/form.tag
+++ b/src/web/app/auth/tags/form.tag
@@ -105,7 +105,7 @@
 						font-size 16px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.session = this.opts.session;
diff --git a/src/web/app/auth/tags/index.tag b/src/web/app/auth/tags/index.tag
index 195c669094..e6b1cdb3f6 100644
--- a/src/web/app/auth/tags/index.tag
+++ b/src/web/app/auth/tags/index.tag
@@ -83,7 +83,7 @@
 					margin 0 auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/ch/tags/channel.tag b/src/web/app/ch/tags/channel.tag
index b01c2b5481..a706a247f5 100644
--- a/src/web/app/ch/tags/channel.tag
+++ b/src/web/app/ch/tags/channel.tag
@@ -53,7 +53,7 @@
 					max-width 500px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import Progress from '../../common/scripts/loading';
 		import ChannelStream from '../../common/scripts/streaming/channel-stream';
 
@@ -228,7 +228,7 @@
 							vertical-align bottom
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.post = this.opts.post;
 		this.form = this.opts.form;
 
@@ -282,7 +282,7 @@
 				display none
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.channel = this.opts.channel;
@@ -375,7 +375,7 @@
 
 <mk-twitter-button>
 	<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-show-count="false">Tweet</a>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			const head = document.getElementsByTagName('head')[0];
 			const script = document.createElement('script');
@@ -388,7 +388,7 @@
 
 <mk-line-button>
 	<div class="line-it-button" data-lang="ja" data-type="share-a" data-url={ _CH_URL_ } style="display: none;"></div>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			const head = document.getElementsByTagName('head')[0];
 			const script = document.createElement('script');
diff --git a/src/web/app/ch/tags/header.tag b/src/web/app/ch/tags/header.tag
index 84575b03d6..47a1e3e76a 100644
--- a/src/web/app/ch/tags/header.tag
+++ b/src/web/app/ch/tags/header.tag
@@ -14,7 +14,7 @@
 				margin-left auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 	</script>
 </mk-header>
diff --git a/src/web/app/ch/tags/index.tag b/src/web/app/ch/tags/index.tag
index e058da6a3f..6e0b451e8a 100644
--- a/src/web/app/ch/tags/index.tag
+++ b/src/web/app/ch/tags/index.tag
@@ -11,7 +11,7 @@
 			display block
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.on('mount', () => {
diff --git a/src/web/app/common/tags/activity-table.tag b/src/web/app/common/tags/activity-table.tag
index 39d4d7205e..2f716912f3 100644
--- a/src/web/app/common/tags/activity-table.tag
+++ b/src/web/app/common/tags/activity-table.tag
@@ -25,7 +25,7 @@
 					transform-origin center
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
diff --git a/src/web/app/common/tags/authorized-apps.tag b/src/web/app/common/tags/authorized-apps.tag
index 0511c1bc6d..26efa1316f 100644
--- a/src/web/app/common/tags/authorized-apps.tag
+++ b/src/web/app/common/tags/authorized-apps.tag
@@ -18,7 +18,7 @@
 					border-bottom solid 1px #eee
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.apps = [];
diff --git a/src/web/app/common/tags/error.tag b/src/web/app/common/tags/error.tag
index f72f403a9e..6cf13666d2 100644
--- a/src/web/app/common/tags/error.tag
+++ b/src/web/app/common/tags/error.tag
@@ -75,7 +75,7 @@
 					height 150px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.troubleshooting = false;
 
 		this.on('mount', () => {
@@ -169,7 +169,7 @@
 						color #ad4339
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			this.update({
 				network: navigator.onLine
diff --git a/src/web/app/common/tags/file-type-icon.tag b/src/web/app/common/tags/file-type-icon.tag
index d47f96fd09..a3e479273f 100644
--- a/src/web/app/common/tags/file-type-icon.tag
+++ b/src/web/app/common/tags/file-type-icon.tag
@@ -4,7 +4,7 @@
 		:scope
 			display inline
 	</style>
-	<script>
+	<script lang="typescript">
 		this.kind = this.opts.type.split('/')[0];
 	</script>
 </mk-file-type-icon>
diff --git a/src/web/app/common/tags/messaging/form.tag b/src/web/app/common/tags/messaging/form.tag
index df0658741f..e9d2c01caa 100644
--- a/src/web/app/common/tags/messaging/form.tag
+++ b/src/web/app/common/tags/messaging/form.tag
@@ -116,7 +116,7 @@
 				display none
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.onpaste = e => {
diff --git a/src/web/app/common/tags/messaging/index.tag b/src/web/app/common/tags/messaging/index.tag
index fa12a78d8f..6c25452c0f 100644
--- a/src/web/app/common/tags/messaging/index.tag
+++ b/src/web/app/common/tags/messaging/index.tag
@@ -329,7 +329,7 @@
 								margin 0 12px 0 0
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/common/tags/messaging/message.tag b/src/web/app/common/tags/messaging/message.tag
index 4f75e9049f..2f193aa5d1 100644
--- a/src/web/app/common/tags/messaging/message.tag
+++ b/src/web/app/common/tags/messaging/message.tag
@@ -205,7 +205,7 @@
 						opacity 0.5
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../../common/scripts/text-compiler';
 
 		this.mixin('i');
diff --git a/src/web/app/common/tags/messaging/room.tag b/src/web/app/common/tags/messaging/room.tag
index e659b778b6..91b93c4827 100644
--- a/src/web/app/common/tags/messaging/room.tag
+++ b/src/web/app/common/tags/messaging/room.tag
@@ -161,7 +161,7 @@
 						//background rgba(0, 0, 0, 0.2)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import MessagingStreamConnection from '../../scripts/streaming/messaging-stream';
 
 		this.mixin('i');
diff --git a/src/web/app/common/tags/nav-links.tag b/src/web/app/common/tags/nav-links.tag
index 3766e5c0a6..3f2613c16d 100644
--- a/src/web/app/common/tags/nav-links.tag
+++ b/src/web/app/common/tags/nav-links.tag
@@ -4,7 +4,7 @@
 		:scope
 			display inline
 	</style>
-	<script>
+	<script lang="typescript">
 		this.aboutUrl = `${_DOCS_URL_}/${_LANG_}/about`;
 	</script>
 </mk-nav-links>
diff --git a/src/web/app/common/tags/number.tag b/src/web/app/common/tags/number.tag
index 4b1081a87c..9cbbacd2c7 100644
--- a/src/web/app/common/tags/number.tag
+++ b/src/web/app/common/tags/number.tag
@@ -3,7 +3,7 @@
 		:scope
 			display inline
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			let value = this.opts.value;
 			const max = this.opts.max;
diff --git a/src/web/app/common/tags/poll-editor.tag b/src/web/app/common/tags/poll-editor.tag
index 1d57eb9de5..0de26f6547 100644
--- a/src/web/app/common/tags/poll-editor.tag
+++ b/src/web/app/common/tags/poll-editor.tag
@@ -85,7 +85,7 @@
 					color darken($theme-color, 30%)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.choices = ['', ''];
 
 		this.oninput = (i, e) => {
diff --git a/src/web/app/common/tags/poll.tag b/src/web/app/common/tags/poll.tag
index e6971d5bb2..c0605d890b 100644
--- a/src/web/app/common/tags/poll.tag
+++ b/src/web/app/common/tags/poll.tag
@@ -67,7 +67,7 @@
 						background transparent
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.init = post => {
diff --git a/src/web/app/common/tags/post-menu.tag b/src/web/app/common/tags/post-menu.tag
index f3b13c0b12..c2b362e8b5 100644
--- a/src/web/app/common/tags/post-menu.tag
+++ b/src/web/app/common/tags/post-menu.tag
@@ -74,7 +74,7 @@
 					display block
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.mixin('i');
diff --git a/src/web/app/common/tags/raw.tag b/src/web/app/common/tags/raw.tag
index 55de0962e9..149ac6c4bf 100644
--- a/src/web/app/common/tags/raw.tag
+++ b/src/web/app/common/tags/raw.tag
@@ -3,7 +3,7 @@
 		:scope
 			display inline
 	</style>
-	<script>
+	<script lang="typescript">
 		this.root.innerHTML = this.opts.content;
 
 		this.on('updated', () => {
diff --git a/src/web/app/common/tags/reaction-picker.vue b/src/web/app/common/tags/reaction-picker.vue
index 307b158c62..8f0f8956e7 100644
--- a/src/web/app/common/tags/reaction-picker.vue
+++ b/src/web/app/common/tags/reaction-picker.vue
@@ -18,7 +18,7 @@
 </div>
 </template>
 
-<script>
+<script lang="typescript">
 	import anime from 'animejs';
 	import api from '../scripts/api';
 
diff --git a/src/web/app/common/tags/reactions-viewer.vue b/src/web/app/common/tags/reactions-viewer.vue
index 18002c9727..32fa50801a 100644
--- a/src/web/app/common/tags/reactions-viewer.vue
+++ b/src/web/app/common/tags/reactions-viewer.vue
@@ -14,7 +14,7 @@
 </div>
 </template>
 
-<script>
+<script lang="typescript">
 	export default {
 		props: ['post'],
 		computed: {
diff --git a/src/web/app/common/tags/signin-history.tag b/src/web/app/common/tags/signin-history.tag
index e6b57c091f..cc9d2113f8 100644
--- a/src/web/app/common/tags/signin-history.tag
+++ b/src/web/app/common/tags/signin-history.tag
@@ -7,7 +7,7 @@
 			display block
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
@@ -97,7 +97,7 @@
 
 	</style>
 
-	<script>
+	<script lang="typescript">
 		import hljs from 'highlight.js';
 
 		this.rec = this.opts.rec;
diff --git a/src/web/app/common/tags/signin.tag b/src/web/app/common/tags/signin.tag
index 3fa253fbbb..441a8ec56c 100644
--- a/src/web/app/common/tags/signin.tag
+++ b/src/web/app/common/tags/signin.tag
@@ -100,7 +100,7 @@
 						opacity 0.7
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = null;
diff --git a/src/web/app/common/tags/signup.tag b/src/web/app/common/tags/signup.tag
index 1efb4aa09f..4e79de787b 100644
--- a/src/web/app/common/tags/signup.tag
+++ b/src/web/app/common/tags/signup.tag
@@ -173,7 +173,7 @@
 						background darken($theme-color, 5%)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 		const getPasswordStrength = require('syuilo-password-strength');
 
diff --git a/src/web/app/common/tags/special-message.tag b/src/web/app/common/tags/special-message.tag
index 24fe66652f..da903c6325 100644
--- a/src/web/app/common/tags/special-message.tag
+++ b/src/web/app/common/tags/special-message.tag
@@ -19,7 +19,7 @@
 				background #ff1036
 
 	</style>
-	<script>
+	<script lang="typescript">
 		const now = new Date();
 		this.d = now.getDate();
 		this.m = now.getMonth() + 1;
diff --git a/src/web/app/common/tags/stream-indicator.vue b/src/web/app/common/tags/stream-indicator.vue
index 6964cda345..ea8fa5adfe 100644
--- a/src/web/app/common/tags/stream-indicator.vue
+++ b/src/web/app/common/tags/stream-indicator.vue
@@ -15,7 +15,7 @@
 	</div>
 </template>
 
-<script>
+<script lang="typescript">
 	import anime from 'animejs';
 	import Ellipsis from './ellipsis.vue';
 
diff --git a/src/web/app/common/tags/time.vue b/src/web/app/common/tags/time.vue
index 14f38eb2db..82d8ecbfd0 100644
--- a/src/web/app/common/tags/time.vue
+++ b/src/web/app/common/tags/time.vue
@@ -6,7 +6,7 @@
 	</time>
 </template>
 
-<script>
+<script lang="typescript">
 	export default {
 		props: ['time', 'mode'],
 		data: {
diff --git a/src/web/app/common/tags/twitter-setting.tag b/src/web/app/common/tags/twitter-setting.tag
index cb3d1e56ad..935239f44e 100644
--- a/src/web/app/common/tags/twitter-setting.tag
+++ b/src/web/app/common/tags/twitter-setting.tag
@@ -24,7 +24,7 @@
 			.id
 				color #8899a6
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 
 		this.form = null;
diff --git a/src/web/app/common/tags/uploader.tag b/src/web/app/common/tags/uploader.tag
index cc555304dd..1dbfff96fb 100644
--- a/src/web/app/common/tags/uploader.tag
+++ b/src/web/app/common/tags/uploader.tag
@@ -138,7 +138,7 @@
 							to   {background-position: -64px 32px;}
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 
 		this.uploads = [];
diff --git a/src/web/app/desktop/tags/analog-clock.tag b/src/web/app/desktop/tags/analog-clock.tag
index dda5a4b30e..6b2bce3b2c 100644
--- a/src/web/app/desktop/tags/analog-clock.tag
+++ b/src/web/app/desktop/tags/analog-clock.tag
@@ -7,7 +7,7 @@
 				width 256px
 				height 256px
 	</style>
-	<script>
+	<script lang="typescript">
 		const Vec2 = function(x, y) {
 			this.x = x;
 			this.y = y;
diff --git a/src/web/app/desktop/tags/autocomplete-suggestion.tag b/src/web/app/desktop/tags/autocomplete-suggestion.tag
index ec531a1b2d..a0215666c0 100644
--- a/src/web/app/desktop/tags/autocomplete-suggestion.tag
+++ b/src/web/app/desktop/tags/autocomplete-suggestion.tag
@@ -79,7 +79,7 @@
 						color rgba(0, 0, 0, 0.3)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import contains from '../../common/scripts/contains';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/big-follow-button.tag b/src/web/app/desktop/tags/big-follow-button.tag
index faac04a9f6..6d43e4abeb 100644
--- a/src/web/app/desktop/tags/big-follow-button.tag
+++ b/src/web/app/desktop/tags/big-follow-button.tag
@@ -73,7 +73,7 @@
 					opacity 0.7
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import isPromise from '../../common/scripts/is-promise';
 
 		this.mixin('i');
diff --git a/src/web/app/desktop/tags/contextmenu.tag b/src/web/app/desktop/tags/contextmenu.tag
index 09d989c09c..67bdc58242 100644
--- a/src/web/app/desktop/tags/contextmenu.tag
+++ b/src/web/app/desktop/tags/contextmenu.tag
@@ -95,7 +95,7 @@
 				transition visibility 0s linear 0.2s
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 		import contains from '../../common/scripts/contains';
 
diff --git a/src/web/app/desktop/tags/crop-window.tag b/src/web/app/desktop/tags/crop-window.tag
index 43bbcb8c58..1749986b2b 100644
--- a/src/web/app/desktop/tags/crop-window.tag
+++ b/src/web/app/desktop/tags/crop-window.tag
@@ -159,7 +159,7 @@
 							width 150px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		const Cropper = require('cropperjs');
 
 		this.image = this.opts.file;
diff --git a/src/web/app/desktop/tags/detailed-post-window.tag b/src/web/app/desktop/tags/detailed-post-window.tag
index d5042612c4..57e390d50d 100644
--- a/src/web/app/desktop/tags/detailed-post-window.tag
+++ b/src/web/app/desktop/tags/detailed-post-window.tag
@@ -34,7 +34,7 @@
 					margin 0 auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/dialog.tag b/src/web/app/desktop/tags/dialog.tag
index 92ea0b2b11..cb8c0f31ba 100644
--- a/src/web/app/desktop/tags/dialog.tag
+++ b/src/web/app/desktop/tags/dialog.tag
@@ -82,7 +82,7 @@
 							transition color 0s ease
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.canThrough = opts.canThrough != null ? opts.canThrough : true;
diff --git a/src/web/app/desktop/tags/donation.tag b/src/web/app/desktop/tags/donation.tag
index 8a711890fa..fe446f2e61 100644
--- a/src/web/app/desktop/tags/donation.tag
+++ b/src/web/app/desktop/tags/donation.tag
@@ -46,7 +46,7 @@
 					margin-bottom 16px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/desktop/tags/drive/base-contextmenu.tag b/src/web/app/desktop/tags/drive/base-contextmenu.tag
index d2381cc471..f81526bef0 100644
--- a/src/web/app/desktop/tags/drive/base-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/base-contextmenu.tag
@@ -12,7 +12,7 @@
 			</li>
 		</ul>
 	</mk-contextmenu>
-	<script>
+	<script lang="typescript">
 		this.browser = this.opts.browser;
 
 		this.on('mount', () => {
diff --git a/src/web/app/desktop/tags/drive/browser-window.tag b/src/web/app/desktop/tags/drive/browser-window.tag
index af225e00cd..db7b898341 100644
--- a/src/web/app/desktop/tags/drive/browser-window.tag
+++ b/src/web/app/desktop/tags/drive/browser-window.tag
@@ -27,7 +27,7 @@
 						height 100%
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.folder = this.opts.folder ? this.opts.folder : null;
diff --git a/src/web/app/desktop/tags/drive/browser.tag b/src/web/app/desktop/tags/drive/browser.tag
index 9b9a42cc26..15c9bb5698 100644
--- a/src/web/app/desktop/tags/drive/browser.tag
+++ b/src/web/app/desktop/tags/drive/browser.tag
@@ -242,7 +242,7 @@
 				display none
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import contains from '../../../common/scripts/contains';
 		import dialog from '../../scripts/dialog';
 		import inputDialog from '../../scripts/input-dialog';
diff --git a/src/web/app/desktop/tags/drive/file-contextmenu.tag b/src/web/app/desktop/tags/drive/file-contextmenu.tag
index bb934d35e5..c7eeb01cd1 100644
--- a/src/web/app/desktop/tags/drive/file-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/file-contextmenu.tag
@@ -34,7 +34,7 @@
 			</li>
 		</ul>
 	</mk-contextmenu>
-	<script>
+	<script lang="typescript">
 		import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
 		import dialog from '../../scripts/dialog';
 		import inputDialog from '../../scripts/input-dialog';
diff --git a/src/web/app/desktop/tags/drive/file.tag b/src/web/app/desktop/tags/drive/file.tag
index c55953cc71..a669f5fff4 100644
--- a/src/web/app/desktop/tags/drive/file.tag
+++ b/src/web/app/desktop/tags/drive/file.tag
@@ -140,7 +140,7 @@
 					opacity 0.5
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 		import bytesToSize from '../../../common/scripts/bytes-to-size';
 
diff --git a/src/web/app/desktop/tags/drive/folder-contextmenu.tag b/src/web/app/desktop/tags/drive/folder-contextmenu.tag
index 43cad3da55..d4c2f93801 100644
--- a/src/web/app/desktop/tags/drive/folder-contextmenu.tag
+++ b/src/web/app/desktop/tags/drive/folder-contextmenu.tag
@@ -17,7 +17,7 @@
 			</li>
 		</ul>
 	</mk-contextmenu>
-	<script>
+	<script lang="typescript">
 		import inputDialog from '../../scripts/input-dialog';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/drive/folder.tag b/src/web/app/desktop/tags/drive/folder.tag
index 90d9f2b3ca..1ba166a674 100644
--- a/src/web/app/desktop/tags/drive/folder.tag
+++ b/src/web/app/desktop/tags/drive/folder.tag
@@ -47,7 +47,7 @@
 					text-align left
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import dialog from '../../scripts/dialog';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/drive/nav-folder.tag b/src/web/app/desktop/tags/drive/nav-folder.tag
index 9c943f26e6..2afbb50f0e 100644
--- a/src/web/app/desktop/tags/drive/nav-folder.tag
+++ b/src/web/app/desktop/tags/drive/nav-folder.tag
@@ -6,7 +6,7 @@
 				background #eee
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.folder = this.opts.folder ? this.opts.folder : null;
diff --git a/src/web/app/desktop/tags/follow-button.tag b/src/web/app/desktop/tags/follow-button.tag
index aa7e34321e..843774ad07 100644
--- a/src/web/app/desktop/tags/follow-button.tag
+++ b/src/web/app/desktop/tags/follow-button.tag
@@ -70,7 +70,7 @@
 					opacity 0.7
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import isPromise from '../../common/scripts/is-promise';
 
 		this.mixin('i');
diff --git a/src/web/app/desktop/tags/following-setuper.tag b/src/web/app/desktop/tags/following-setuper.tag
index 8aeb8a3f09..75ce76ae53 100644
--- a/src/web/app/desktop/tags/following-setuper.tag
+++ b/src/web/app/desktop/tags/following-setuper.tag
@@ -120,7 +120,7 @@
 					padding 14px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 		this.mixin('user-preview');
 
diff --git a/src/web/app/desktop/tags/home-widgets/access-log.tag b/src/web/app/desktop/tags/home-widgets/access-log.tag
index 1e9ea0fdb5..c3adc0d8b9 100644
--- a/src/web/app/desktop/tags/home-widgets/access-log.tag
+++ b/src/web/app/desktop/tags/home-widgets/access-log.tag
@@ -47,7 +47,7 @@
 						margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import seedrandom from 'seedrandom';
 
 		this.data = {
diff --git a/src/web/app/desktop/tags/home-widgets/activity.tag b/src/web/app/desktop/tags/home-widgets/activity.tag
index 5cc5422725..878de6d13a 100644
--- a/src/web/app/desktop/tags/home-widgets/activity.tag
+++ b/src/web/app/desktop/tags/home-widgets/activity.tag
@@ -4,7 +4,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			view: 0,
 			design: 0
diff --git a/src/web/app/desktop/tags/home-widgets/broadcast.tag b/src/web/app/desktop/tags/home-widgets/broadcast.tag
index 963b31237a..e1ba82e79b 100644
--- a/src/web/app/desktop/tags/home-widgets/broadcast.tag
+++ b/src/web/app/desktop/tags/home-widgets/broadcast.tag
@@ -97,7 +97,7 @@
 				font-size 0.7em
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			design: 0
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/calendar.tag b/src/web/app/desktop/tags/home-widgets/calendar.tag
index a304d62554..46d47662b9 100644
--- a/src/web/app/desktop/tags/home-widgets/calendar.tag
+++ b/src/web/app/desktop/tags/home-widgets/calendar.tag
@@ -111,7 +111,7 @@
 							background #41ddde
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			design: 0
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/channel.tag b/src/web/app/desktop/tags/home-widgets/channel.tag
index 3fc1f1abfb..0b4fbbf4f2 100644
--- a/src/web/app/desktop/tags/home-widgets/channel.tag
+++ b/src/web/app/desktop/tags/home-widgets/channel.tag
@@ -55,7 +55,7 @@
 				height 200px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			channel: null,
 			compact: false
@@ -137,7 +137,7 @@
 				bottom 0
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import ChannelStream from '../../../common/scripts/streaming/channel-stream';
 
 		this.mixin('api');
@@ -241,7 +241,7 @@
 							vertical-align bottom
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.post = this.opts.post;
 		this.form = this.opts.form;
 
@@ -275,7 +275,7 @@
 					border-color #aeaeae
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.clear = () => {
diff --git a/src/web/app/desktop/tags/home-widgets/donation.tag b/src/web/app/desktop/tags/home-widgets/donation.tag
index 327cae5a06..5ed5c137b5 100644
--- a/src/web/app/desktop/tags/home-widgets/donation.tag
+++ b/src/web/app/desktop/tags/home-widgets/donation.tag
@@ -29,7 +29,7 @@
 					color #999
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('widget');
 		this.mixin('user-preview');
 	</script>
diff --git a/src/web/app/desktop/tags/home-widgets/mentions.tag b/src/web/app/desktop/tags/home-widgets/mentions.tag
index d4569216c6..2ca1fa502d 100644
--- a/src/web/app/desktop/tags/home-widgets/mentions.tag
+++ b/src/web/app/desktop/tags/home-widgets/mentions.tag
@@ -52,7 +52,7 @@
 					color #ccc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/desktop/tags/home-widgets/messaging.tag b/src/web/app/desktop/tags/home-widgets/messaging.tag
index b5edd36fd2..cd11c21a23 100644
--- a/src/web/app/desktop/tags/home-widgets/messaging.tag
+++ b/src/web/app/desktop/tags/home-widgets/messaging.tag
@@ -29,7 +29,7 @@
 				overflow auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			design: 0
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/nav.tag b/src/web/app/desktop/tags/home-widgets/nav.tag
index 3086524333..890fb4d8f7 100644
--- a/src/web/app/desktop/tags/home-widgets/nav.tag
+++ b/src/web/app/desktop/tags/home-widgets/nav.tag
@@ -17,7 +17,7 @@
 				color #ccc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('widget');
 	</script>
 </mk-nav-home-widget>
diff --git a/src/web/app/desktop/tags/home-widgets/notifications.tag b/src/web/app/desktop/tags/home-widgets/notifications.tag
index 4a6d7b4170..4c48da6592 100644
--- a/src/web/app/desktop/tags/home-widgets/notifications.tag
+++ b/src/web/app/desktop/tags/home-widgets/notifications.tag
@@ -46,7 +46,7 @@
 				overflow auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			compact: false
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/photo-stream.tag b/src/web/app/desktop/tags/home-widgets/photo-stream.tag
index 6040e46119..8c57dbbef2 100644
--- a/src/web/app/desktop/tags/home-widgets/photo-stream.tag
+++ b/src/web/app/desktop/tags/home-widgets/photo-stream.tag
@@ -69,7 +69,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			design: 0
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/post-form.tag b/src/web/app/desktop/tags/home-widgets/post-form.tag
index a3dc3dd6e5..58ceac6040 100644
--- a/src/web/app/desktop/tags/home-widgets/post-form.tag
+++ b/src/web/app/desktop/tags/home-widgets/post-form.tag
@@ -62,7 +62,7 @@
 					transition background 0s ease
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			design: 0
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/profile.tag b/src/web/app/desktop/tags/home-widgets/profile.tag
index 30ca3c3b63..02a1f0d5a3 100644
--- a/src/web/app/desktop/tags/home-widgets/profile.tag
+++ b/src/web/app/desktop/tags/home-widgets/profile.tag
@@ -87,7 +87,7 @@
 				color #999
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import inputDialog from '../../scripts/input-dialog';
 		import updateAvatar from '../../scripts/update-avatar';
 		import updateBanner from '../../scripts/update-banner';
diff --git a/src/web/app/desktop/tags/home-widgets/recommended-polls.tag b/src/web/app/desktop/tags/home-widgets/recommended-polls.tag
index cf76ea9c14..f33b2de5fb 100644
--- a/src/web/app/desktop/tags/home-widgets/recommended-polls.tag
+++ b/src/web/app/desktop/tags/home-widgets/recommended-polls.tag
@@ -73,7 +73,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			compact: false
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/rss-reader.tag b/src/web/app/desktop/tags/home-widgets/rss-reader.tag
index 916281def2..f8a0787d3a 100644
--- a/src/web/app/desktop/tags/home-widgets/rss-reader.tag
+++ b/src/web/app/desktop/tags/home-widgets/rss-reader.tag
@@ -65,7 +65,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			compact: false
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/server.tag b/src/web/app/desktop/tags/home-widgets/server.tag
index cae2306a5f..1a15d37043 100644
--- a/src/web/app/desktop/tags/home-widgets/server.tag
+++ b/src/web/app/desktop/tags/home-widgets/server.tag
@@ -61,7 +61,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('os');
 
 		this.data = {
@@ -186,7 +186,7 @@
 				display block
 				clear both
 	</style>
-	<script>
+	<script lang="typescript">
 		import uuid from 'uuid';
 
 		this.viewBoxX = 50;
@@ -270,7 +270,7 @@
 				clear both
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.cores = this.opts.meta.cpu.cores;
 		this.model = this.opts.meta.cpu.model;
 		this.connection = this.opts.connection;
@@ -328,7 +328,7 @@
 				clear both
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import bytesToSize from '../../../common/scripts/bytes-to-size';
 
 		this.connection = this.opts.connection;
@@ -394,7 +394,7 @@
 				clear both
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import bytesToSize from '../../../common/scripts/bytes-to-size';
 
 		this.connection = this.opts.connection;
@@ -440,7 +440,7 @@
 					font-weight bold
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.connection = this.opts.connection;
 
 		this.on('mount', () => {
@@ -475,7 +475,7 @@
 				color #505050
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.meta = this.opts.meta;
 	</script>
 </mk-server-home-widget-info>
@@ -516,7 +516,7 @@
 					fill rgba(0, 0, 0, 0.6)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.r = 0.4;
 
 		this.render = p => {
diff --git a/src/web/app/desktop/tags/home-widgets/slideshow.tag b/src/web/app/desktop/tags/home-widgets/slideshow.tag
index ab78ca2c67..817b138d31 100644
--- a/src/web/app/desktop/tags/home-widgets/slideshow.tag
+++ b/src/web/app/desktop/tags/home-widgets/slideshow.tag
@@ -48,7 +48,7 @@
 						opacity 0
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.data = {
diff --git a/src/web/app/desktop/tags/home-widgets/timeline.tag b/src/web/app/desktop/tags/home-widgets/timeline.tag
index 2bbee14fab..67e56b6767 100644
--- a/src/web/app/desktop/tags/home-widgets/timeline.tag
+++ b/src/web/app/desktop/tags/home-widgets/timeline.tag
@@ -38,7 +38,7 @@
 					color #ccc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/desktop/tags/home-widgets/timemachine.tag b/src/web/app/desktop/tags/home-widgets/timemachine.tag
index e47ce2d4a8..43f59fe674 100644
--- a/src/web/app/desktop/tags/home-widgets/timemachine.tag
+++ b/src/web/app/desktop/tags/home-widgets/timemachine.tag
@@ -4,7 +4,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			design: 0
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/tips.tag b/src/web/app/desktop/tags/home-widgets/tips.tag
index 2135a836c9..a352253cef 100644
--- a/src/web/app/desktop/tags/home-widgets/tips.tag
+++ b/src/web/app/desktop/tags/home-widgets/tips.tag
@@ -26,7 +26,7 @@
 					border-radius 2px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.mixin('widget');
diff --git a/src/web/app/desktop/tags/home-widgets/trends.tag b/src/web/app/desktop/tags/home-widgets/trends.tag
index db2ed95100..4e5060a3e0 100644
--- a/src/web/app/desktop/tags/home-widgets/trends.tag
+++ b/src/web/app/desktop/tags/home-widgets/trends.tag
@@ -75,7 +75,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			compact: false
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
index 25a60b95ae..fb23eac5e7 100644
--- a/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
+++ b/src/web/app/desktop/tags/home-widgets/user-recommendation.tag
@@ -114,7 +114,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = {
 			compact: false
 		};
diff --git a/src/web/app/desktop/tags/home-widgets/version.tag b/src/web/app/desktop/tags/home-widgets/version.tag
index aeebb53b00..6dd8ad6444 100644
--- a/src/web/app/desktop/tags/home-widgets/version.tag
+++ b/src/web/app/desktop/tags/home-widgets/version.tag
@@ -14,7 +14,7 @@
 				color #aaa
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('widget');
 	</script>
 </mk-version-home-widget>
diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag
index f727c3e808..827622930d 100644
--- a/src/web/app/desktop/tags/home.tag
+++ b/src/web/app/desktop/tags/home.tag
@@ -180,7 +180,7 @@
 						margin 0 auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import uuid from 'uuid';
 		import Sortable from 'sortablejs';
 		import dialog from '../scripts/dialog';
diff --git a/src/web/app/desktop/tags/images.tag b/src/web/app/desktop/tags/images.tag
index 088f937e72..594c706be5 100644
--- a/src/web/app/desktop/tags/images.tag
+++ b/src/web/app/desktop/tags/images.tag
@@ -8,7 +8,7 @@
 			grid-gap 4px
 			height 256px
 	</style>
-	<script>
+	<script lang="typescript">
 		this.images = this.opts.images;
 
 		this.on('mount', () => {
@@ -78,7 +78,7 @@
 					background-size cover
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.image = this.opts.image;
 		this.styles = {
 			'background-color': this.image.properties.average_color ? `rgb(${this.image.properties.average_color.join(',')})` : 'transparent',
@@ -145,7 +145,7 @@
 				cursor zoom-out
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.image = this.opts.image;
diff --git a/src/web/app/desktop/tags/input-dialog.tag b/src/web/app/desktop/tags/input-dialog.tag
index 26fa384e61..a1634429cf 100644
--- a/src/web/app/desktop/tags/input-dialog.tag
+++ b/src/web/app/desktop/tags/input-dialog.tag
@@ -119,7 +119,7 @@
 								border-color #dcdcdc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.done = false;
 
 		this.title = this.opts.title;
diff --git a/src/web/app/desktop/tags/list-user.tag b/src/web/app/desktop/tags/list-user.tag
index 45c4deb535..bde90b1cc6 100644
--- a/src/web/app/desktop/tags/list-user.tag
+++ b/src/web/app/desktop/tags/list-user.tag
@@ -89,5 +89,5 @@
 				right 16px
 
 	</style>
-	<script>this.user = this.opts.user</script>
+	<script lang="typescript">this.user = this.opts.user</script>
 </mk-list-user>
diff --git a/src/web/app/desktop/tags/messaging/room-window.tag b/src/web/app/desktop/tags/messaging/room-window.tag
index b13c2d3e90..ca11873644 100644
--- a/src/web/app/desktop/tags/messaging/room-window.tag
+++ b/src/web/app/desktop/tags/messaging/room-window.tag
@@ -18,7 +18,7 @@
 						overflow auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.user = this.opts.user;
 
 		this.popout = `${_URL_}/i/messaging/${this.user.username}`;
diff --git a/src/web/app/desktop/tags/messaging/window.tag b/src/web/app/desktop/tags/messaging/window.tag
index ac5513a3f4..e078bccad7 100644
--- a/src/web/app/desktop/tags/messaging/window.tag
+++ b/src/web/app/desktop/tags/messaging/window.tag
@@ -18,7 +18,7 @@
 						overflow auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			this.$refs.window.on('closed', () => {
 				this.$destroy();
diff --git a/src/web/app/desktop/tags/notifications.tag b/src/web/app/desktop/tags/notifications.tag
index 6a16db1357..7bba90a8b6 100644
--- a/src/web/app/desktop/tags/notifications.tag
+++ b/src/web/app/desktop/tags/notifications.tag
@@ -214,7 +214,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import getPostSummary from '../../../../common/get-post-summary.ts';
 		this.getPostSummary = getPostSummary;
 
diff --git a/src/web/app/desktop/tags/pages/drive.tag b/src/web/app/desktop/tags/pages/drive.tag
index 12ebcc47c7..f4e2a3740a 100644
--- a/src/web/app/desktop/tags/pages/drive.tag
+++ b/src/web/app/desktop/tags/pages/drive.tag
@@ -11,7 +11,7 @@
 			> mk-drive-browser
 				height 100%
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			document.title = 'Misskey Drive';
 
diff --git a/src/web/app/desktop/tags/pages/entrance.tag b/src/web/app/desktop/tags/pages/entrance.tag
index c516bdb382..56cec34909 100644
--- a/src/web/app/desktop/tags/pages/entrance.tag
+++ b/src/web/app/desktop/tags/pages/entrance.tag
@@ -107,7 +107,7 @@
 						font-size 10px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.mode = 'signin';
@@ -278,7 +278,7 @@
 				color #666
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			this.$refs.signin.on('user', user => {
 				this.update({
diff --git a/src/web/app/desktop/tags/pages/home-customize.tag b/src/web/app/desktop/tags/pages/home-customize.tag
index ad74e095d5..178558f9d7 100644
--- a/src/web/app/desktop/tags/pages/home-customize.tag
+++ b/src/web/app/desktop/tags/pages/home-customize.tag
@@ -4,7 +4,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			document.title = 'Misskey - ホームのカスタマイズ';
 		});
diff --git a/src/web/app/desktop/tags/pages/home.tag b/src/web/app/desktop/tags/pages/home.tag
index 206592518b..9b9d455b5b 100644
--- a/src/web/app/desktop/tags/pages/home.tag
+++ b/src/web/app/desktop/tags/pages/home.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import Progress from '../../../common/scripts/loading';
 		import getPostSummary from '../../../../../common/get-post-summary.ts';
 
diff --git a/src/web/app/desktop/tags/pages/messaging-room.tag b/src/web/app/desktop/tags/pages/messaging-room.tag
index 54bd38e57b..bfa8c2465e 100644
--- a/src/web/app/desktop/tags/pages/messaging-room.tag
+++ b/src/web/app/desktop/tags/pages/messaging-room.tag
@@ -7,7 +7,7 @@
 			background #fff
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import Progress from '../../../common/scripts/loading';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/pages/post.tag b/src/web/app/desktop/tags/pages/post.tag
index b5cfea3add..488adc6e39 100644
--- a/src/web/app/desktop/tags/pages/post.tag
+++ b/src/web/app/desktop/tags/pages/post.tag
@@ -31,7 +31,7 @@
 					width 640px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import Progress from '../../../common/scripts/loading';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/pages/search.tag b/src/web/app/desktop/tags/pages/search.tag
index 4d72fad655..eaa80a039c 100644
--- a/src/web/app/desktop/tags/pages/search.tag
+++ b/src/web/app/desktop/tags/pages/search.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import Progress from '../../../common/scripts/loading';
 
 		this.on('mount', () => {
diff --git a/src/web/app/desktop/tags/pages/selectdrive.tag b/src/web/app/desktop/tags/pages/selectdrive.tag
index 723a1dd5aa..dd4d30f412 100644
--- a/src/web/app/desktop/tags/pages/selectdrive.tag
+++ b/src/web/app/desktop/tags/pages/selectdrive.tag
@@ -126,7 +126,7 @@
 						border-color #dcdcdc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		const q = (new URL(location)).searchParams;
 		this.multiple = q.get('multiple') == 'true' ? true : false;
 
diff --git a/src/web/app/desktop/tags/pages/user.tag b/src/web/app/desktop/tags/pages/user.tag
index 8ea47408c2..abed2ef021 100644
--- a/src/web/app/desktop/tags/pages/user.tag
+++ b/src/web/app/desktop/tags/pages/user.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import Progress from '../../../common/scripts/loading';
 
 		this.user = this.opts.user;
diff --git a/src/web/app/desktop/tags/post-detail-sub.tag b/src/web/app/desktop/tags/post-detail-sub.tag
index 0b8d4d1d33..2088056700 100644
--- a/src/web/app/desktop/tags/post-detail-sub.tag
+++ b/src/web/app/desktop/tags/post-detail-sub.tag
@@ -106,7 +106,7 @@
 							margin-top 8px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../common/scripts/text-compiler';
 		import dateStringify from '../../common/scripts/date-stringify';
 
diff --git a/src/web/app/desktop/tags/post-detail.tag b/src/web/app/desktop/tags/post-detail.tag
index a4f88da7db..34b34b6a58 100644
--- a/src/web/app/desktop/tags/post-detail.tag
+++ b/src/web/app/desktop/tags/post-detail.tag
@@ -236,7 +236,7 @@
 						border-top 1px solid #eef0f2
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../common/scripts/text-compiler';
 		import dateStringify from '../../common/scripts/date-stringify';
 
diff --git a/src/web/app/desktop/tags/post-form-window.tag b/src/web/app/desktop/tags/post-form-window.tag
index 80b51df605..562621bde2 100644
--- a/src/web/app/desktop/tags/post-form-window.tag
+++ b/src/web/app/desktop/tags/post-form-window.tag
@@ -37,7 +37,7 @@
 							margin 16px 22px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.uploadingFiles = [];
 		this.files = [];
 
diff --git a/src/web/app/desktop/tags/post-form.tag b/src/web/app/desktop/tags/post-form.tag
index e4a9800cfe..c2da858857 100644
--- a/src/web/app/desktop/tags/post-form.tag
+++ b/src/web/app/desktop/tags/post-form.tag
@@ -282,7 +282,7 @@
 				pointer-events none
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import Sortable from 'sortablejs';
 		import getKao from '../../common/scripts/get-kao';
 		import notify from '../scripts/notify';
diff --git a/src/web/app/desktop/tags/post-preview.tag b/src/web/app/desktop/tags/post-preview.tag
index dcad0ff7c3..eb71e5e879 100644
--- a/src/web/app/desktop/tags/post-preview.tag
+++ b/src/web/app/desktop/tags/post-preview.tag
@@ -82,7 +82,7 @@
 							color #717171
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import dateStringify from '../../common/scripts/date-stringify';
 
 		this.mixin('user-preview');
diff --git a/src/web/app/desktop/tags/progress-dialog.tag b/src/web/app/desktop/tags/progress-dialog.tag
index 2359802be2..5df5d7f57a 100644
--- a/src/web/app/desktop/tags/progress-dialog.tag
+++ b/src/web/app/desktop/tags/progress-dialog.tag
@@ -72,7 +72,7 @@
 								to   {background-position: -64px 32px;}
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.title = this.opts.title;
 		this.value = parseInt(this.opts.value, 10);
 		this.max = parseInt(this.opts.max, 10);
diff --git a/src/web/app/desktop/tags/repost-form-window.tag b/src/web/app/desktop/tags/repost-form-window.tag
index 13a862d974..25f509c626 100644
--- a/src/web/app/desktop/tags/repost-form-window.tag
+++ b/src/web/app/desktop/tags/repost-form-window.tag
@@ -15,7 +15,7 @@
 						margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.onDocumentKeydown = e => {
 			if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
 				if (e.which == 27) { // Esc
diff --git a/src/web/app/desktop/tags/repost-form.tag b/src/web/app/desktop/tags/repost-form.tag
index 06ee32150d..77118124c3 100644
--- a/src/web/app/desktop/tags/repost-form.tag
+++ b/src/web/app/desktop/tags/repost-form.tag
@@ -84,7 +84,7 @@
 						border-color $theme-color
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import notify from '../scripts/notify';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/search-posts.tag b/src/web/app/desktop/tags/search-posts.tag
index 3343697cad..09320c5d72 100644
--- a/src/web/app/desktop/tags/search-posts.tag
+++ b/src/web/app/desktop/tags/search-posts.tag
@@ -32,7 +32,7 @@
 					color #ccc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import parse from '../../common/scripts/parse-search-query';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/search.tag b/src/web/app/desktop/tags/search.tag
index 492999181e..ec6bbfc349 100644
--- a/src/web/app/desktop/tags/search.tag
+++ b/src/web/app/desktop/tags/search.tag
@@ -22,7 +22,7 @@
 				overflow hidden
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.query = this.opts.query;
 
 		this.on('mount', () => {
diff --git a/src/web/app/desktop/tags/select-file-from-drive-window.tag b/src/web/app/desktop/tags/select-file-from-drive-window.tag
index f776f0ecbb..10dc7db9fd 100644
--- a/src/web/app/desktop/tags/select-file-from-drive-window.tag
+++ b/src/web/app/desktop/tags/select-file-from-drive-window.tag
@@ -134,7 +134,7 @@
 								border-color #dcdcdc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.files = [];
 
 		this.multiple = this.opts.multiple != null ? this.opts.multiple : false;
diff --git a/src/web/app/desktop/tags/select-folder-from-drive-window.tag b/src/web/app/desktop/tags/select-folder-from-drive-window.tag
index 317fb90ad4..1cd7527c81 100644
--- a/src/web/app/desktop/tags/select-folder-from-drive-window.tag
+++ b/src/web/app/desktop/tags/select-folder-from-drive-window.tag
@@ -89,7 +89,7 @@
 								border-color #dcdcdc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.files = [];
 
 		this.title = this.opts.title || '%fa:R folder%フォルダを選択';
diff --git a/src/web/app/desktop/tags/set-avatar-suggestion.tag b/src/web/app/desktop/tags/set-avatar-suggestion.tag
index 923871a790..e67a8c66d4 100644
--- a/src/web/app/desktop/tags/set-avatar-suggestion.tag
+++ b/src/web/app/desktop/tags/set-avatar-suggestion.tag
@@ -30,7 +30,7 @@
 					color #fff
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import updateAvatar from '../scripts/update-avatar';
 
 		this.mixin('i');
diff --git a/src/web/app/desktop/tags/set-banner-suggestion.tag b/src/web/app/desktop/tags/set-banner-suggestion.tag
index fa4e5843b7..0d32c9a0e3 100644
--- a/src/web/app/desktop/tags/set-banner-suggestion.tag
+++ b/src/web/app/desktop/tags/set-banner-suggestion.tag
@@ -30,7 +30,7 @@
 					color #fff
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import updateBanner from '../scripts/update-banner';
 
 		this.mixin('i');
diff --git a/src/web/app/desktop/tags/settings-window.tag b/src/web/app/desktop/tags/settings-window.tag
index 64ce1336d9..094225f61f 100644
--- a/src/web/app/desktop/tags/settings-window.tag
+++ b/src/web/app/desktop/tags/settings-window.tag
@@ -16,7 +16,7 @@
 					overflow hidden
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			this.$refs.window.on('closed', () => {
 				this.$destroy();
diff --git a/src/web/app/desktop/tags/settings.tag b/src/web/app/desktop/tags/settings.tag
index 1e3097ba12..3288ba7217 100644
--- a/src/web/app/desktop/tags/settings.tag
+++ b/src/web/app/desktop/tags/settings.tag
@@ -119,7 +119,7 @@
 						border-bottom solid 1px #eee
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.page = 'profile';
 
 		this.setPage = page => {
@@ -166,7 +166,7 @@
 					margin-left 8px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import updateAvatar from '../scripts/update-avatar';
 		import notify from '../scripts/notify';
 
@@ -208,7 +208,7 @@
 				background #eee
 				border-radius 2px
 	</style>
-	<script>
+	<script lang="typescript">
 		import passwordDialog from '../scripts/password-dialog';
 
 		this.mixin('i');
@@ -231,7 +231,7 @@
 			display block
 			color #4a535a
 	</style>
-	<script>
+	<script lang="typescript">
 		import passwordDialog from '../scripts/password-dialog';
 		import dialog from '../scripts/dialog';
 		import notify from '../scripts/notify';
@@ -287,7 +287,7 @@
 			color #4a535a
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import passwordDialog from '../scripts/password-dialog';
 		import notify from '../scripts/notify';
 
@@ -370,7 +370,7 @@
 					fill rgba(0, 0, 0, 0.6)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.r = 0.4;
@@ -408,7 +408,7 @@
 			display block
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.apps = [];
diff --git a/src/web/app/desktop/tags/sub-post-content.tag b/src/web/app/desktop/tags/sub-post-content.tag
index 184fc53eb5..40b3b30058 100644
--- a/src/web/app/desktop/tags/sub-post-content.tag
+++ b/src/web/app/desktop/tags/sub-post-content.tag
@@ -33,7 +33,7 @@
 				font-size 80%
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../common/scripts/text-compiler';
 
 		this.mixin('user-preview');
diff --git a/src/web/app/desktop/tags/timeline.tag b/src/web/app/desktop/tags/timeline.tag
index 98970bfa12..4853533469 100644
--- a/src/web/app/desktop/tags/timeline.tag
+++ b/src/web/app/desktop/tags/timeline.tag
@@ -35,7 +35,7 @@
 				border-bottom-right-radius 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.posts = [];
 
 		this.on('update', () => {
@@ -409,7 +409,7 @@
 				background rgba(0, 0, 0, 0.0125)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../common/scripts/text-compiler';
 		import dateStringify from '../../common/scripts/date-stringify';
 
@@ -693,7 +693,7 @@
 								font-size 80%
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import dateStringify from '../../common/scripts/date-stringify';
 
 		this.mixin('user-preview');
diff --git a/src/web/app/desktop/tags/ui.tag b/src/web/app/desktop/tags/ui.tag
index a8ddcaf93d..0a3849236d 100644
--- a/src/web/app/desktop/tags/ui.tag
+++ b/src/web/app/desktop/tags/ui.tag
@@ -10,7 +10,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 
 		this.openPostForm = () => {
@@ -119,7 +119,7 @@
 									display none
 
 	</style>
-	<script>this.mixin('i');</script>
+	<script lang="typescript">this.mixin('i');</script>
 </mk-ui-header>
 
 <mk-ui-header-search>
@@ -175,7 +175,7 @@
 						box-shadow 0 0 0 2px rgba($theme-color, 0.5) !important
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('page');
 
 		this.onsubmit = e => {
@@ -221,7 +221,7 @@
 					transition background 0s ease
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.post = e => {
 			this.parent.parent.openPostForm();
 		};
@@ -310,7 +310,7 @@
 					overflow auto
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import contains from '../../common/scripts/contains';
 
 		this.mixin('i');
@@ -487,7 +487,7 @@
 							padding 0 12px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
@@ -604,7 +604,7 @@
 				background #899492
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.now = new Date();
 
 		this.draw = () => {
@@ -789,7 +789,7 @@
 								color $theme-color-foreground
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import contains from '../../common/scripts/contains';
 		import signout from '../../common/scripts/signout';
 		this.signout = signout;
@@ -869,7 +869,7 @@
 				text-align center
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.on('mount', () => {
diff --git a/src/web/app/desktop/tags/user-followers-window.tag b/src/web/app/desktop/tags/user-followers-window.tag
index a67888fa7c..82bec6992d 100644
--- a/src/web/app/desktop/tags/user-followers-window.tag
+++ b/src/web/app/desktop/tags/user-followers-window.tag
@@ -15,5 +15,5 @@
 						border-radius 4px
 
 	</style>
-	<script>this.user = this.opts.user</script>
+	<script lang="typescript">this.user = this.opts.user</script>
 </mk-user-followers-window>
diff --git a/src/web/app/desktop/tags/user-followers.tag b/src/web/app/desktop/tags/user-followers.tag
index 79fa871413..a1b44f0f5b 100644
--- a/src/web/app/desktop/tags/user-followers.tag
+++ b/src/web/app/desktop/tags/user-followers.tag
@@ -6,7 +6,7 @@
 			height 100%
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
diff --git a/src/web/app/desktop/tags/user-following-window.tag b/src/web/app/desktop/tags/user-following-window.tag
index dd798a020b..0f1c4b3ea6 100644
--- a/src/web/app/desktop/tags/user-following-window.tag
+++ b/src/web/app/desktop/tags/user-following-window.tag
@@ -15,5 +15,5 @@
 						border-radius 4px
 
 	</style>
-	<script>this.user = this.opts.user</script>
+	<script lang="typescript">this.user = this.opts.user</script>
 </mk-user-following-window>
diff --git a/src/web/app/desktop/tags/user-following.tag b/src/web/app/desktop/tags/user-following.tag
index 260900f951..db46bf110e 100644
--- a/src/web/app/desktop/tags/user-following.tag
+++ b/src/web/app/desktop/tags/user-following.tag
@@ -6,7 +6,7 @@
 			height 100%
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
diff --git a/src/web/app/desktop/tags/user-preview.tag b/src/web/app/desktop/tags/user-preview.tag
index eb3568ce08..00ecfba1bd 100644
--- a/src/web/app/desktop/tags/user-preview.tag
+++ b/src/web/app/desktop/tags/user-preview.tag
@@ -98,7 +98,7 @@
 				right 8px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.mixin('i');
diff --git a/src/web/app/desktop/tags/user-timeline.tag b/src/web/app/desktop/tags/user-timeline.tag
index 427ce9c53e..3baf5db0e4 100644
--- a/src/web/app/desktop/tags/user-timeline.tag
+++ b/src/web/app/desktop/tags/user-timeline.tag
@@ -52,7 +52,7 @@
 					color #ccc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import isPromise from '../../common/scripts/is-promise';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/user.tag b/src/web/app/desktop/tags/user.tag
index 364b95ba72..daf39347f6 100644
--- a/src/web/app/desktop/tags/user.tag
+++ b/src/web/app/desktop/tags/user.tag
@@ -16,7 +16,7 @@
 						overflow hidden
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.username = this.opts.user;
@@ -182,7 +182,7 @@
 							border solid 1px #ddd
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import updateBanner from '../scripts/update-banner';
 
 		this.mixin('i');
@@ -309,7 +309,7 @@
 						margin-right 8px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.age = require('s-age');
 
 		this.mixin('i');
@@ -411,7 +411,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import isPromise from '../../common/scripts/is-promise';
 
 		this.mixin('api');
@@ -539,7 +539,7 @@
 					right 16px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
@@ -612,7 +612,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
@@ -707,7 +707,7 @@
 							color #ccc
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import ScrollFollower from '../scripts/scroll-follower';
 
 		this.mixin('i');
@@ -776,7 +776,7 @@
 							margin-right 8px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			this.trigger('loaded');
 		});
@@ -819,7 +819,7 @@
 					transform-origin center
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import getMedian from '../../common/scripts/get-median';
 
 		this.mixin('api');
diff --git a/src/web/app/desktop/tags/users-list.tag b/src/web/app/desktop/tags/users-list.tag
index 18ba2b77d4..90173bfd25 100644
--- a/src/web/app/desktop/tags/users-list.tag
+++ b/src/web/app/desktop/tags/users-list.tag
@@ -88,7 +88,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 
 		this.limit = 30;
diff --git a/src/web/app/desktop/tags/widgets/activity.tag b/src/web/app/desktop/tags/widgets/activity.tag
index 8aad5337f1..03d253ea20 100644
--- a/src/web/app/desktop/tags/widgets/activity.tag
+++ b/src/web/app/desktop/tags/widgets/activity.tag
@@ -57,7 +57,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.design = this.opts.design || 0;
@@ -127,7 +127,7 @@
 							fill rgba(0, 0, 0, 0.05)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.data = this.opts.data;
 		this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 		const peak = Math.max.apply(null, this.data.map(d => d.total));
@@ -184,7 +184,7 @@
 				width 100%
 				cursor all-scroll
 	</style>
-	<script>
+	<script lang="typescript">
 		this.viewBoxX = 140;
 		this.viewBoxY = 60;
 		this.zoom = 1;
diff --git a/src/web/app/desktop/tags/widgets/calendar.tag b/src/web/app/desktop/tags/widgets/calendar.tag
index c8d2687832..3d2d84e406 100644
--- a/src/web/app/desktop/tags/widgets/calendar.tag
+++ b/src/web/app/desktop/tags/widgets/calendar.tag
@@ -137,7 +137,7 @@
 								background darken($theme-color, 10%)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		if (this.opts.design == null) this.opts.design = 0;
 
 		const eachMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
diff --git a/src/web/app/desktop/tags/window.tag b/src/web/app/desktop/tags/window.tag
index 2b98ab7f0b..dc7a37fff0 100644
--- a/src/web/app/desktop/tags/window.tag
+++ b/src/web/app/desktop/tags/window.tag
@@ -185,7 +185,7 @@
 					height calc(100% - 40px)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 		import contains from '../../common/scripts/contains';
 
diff --git a/src/web/app/dev/tags/new-app-form.tag b/src/web/app/dev/tags/new-app-form.tag
index f753b5ae33..672c315708 100644
--- a/src/web/app/dev/tags/new-app-form.tag
+++ b/src/web/app/dev/tags/new-app-form.tag
@@ -177,7 +177,7 @@
 					border-radius 3px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.nidState = null;
diff --git a/src/web/app/dev/tags/pages/app.tag b/src/web/app/dev/tags/pages/app.tag
index 1e89b47d8f..42937a21b3 100644
--- a/src/web/app/dev/tags/pages/app.tag
+++ b/src/web/app/dev/tags/pages/app.tag
@@ -13,7 +13,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.fetching = true;
diff --git a/src/web/app/dev/tags/pages/apps.tag b/src/web/app/dev/tags/pages/apps.tag
index d11011ca49..f7b8e416e9 100644
--- a/src/web/app/dev/tags/pages/apps.tag
+++ b/src/web/app/dev/tags/pages/apps.tag
@@ -14,7 +14,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.fetching = true;
diff --git a/src/web/app/mobile/tags/drive-folder-selector.tag b/src/web/app/mobile/tags/drive-folder-selector.tag
index 94cf1db41e..a63d90af57 100644
--- a/src/web/app/mobile/tags/drive-folder-selector.tag
+++ b/src/web/app/mobile/tags/drive-folder-selector.tag
@@ -55,7 +55,7 @@
 					-webkit-overflow-scrolling touch
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.cancel = () => {
 			this.trigger('canceled');
 			this.$destroy();
diff --git a/src/web/app/mobile/tags/drive-selector.tag b/src/web/app/mobile/tags/drive-selector.tag
index a837f8b5f4..d3e4f54c2b 100644
--- a/src/web/app/mobile/tags/drive-selector.tag
+++ b/src/web/app/mobile/tags/drive-selector.tag
@@ -59,7 +59,7 @@
 					-webkit-overflow-scrolling touch
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.files = [];
 
 		this.on('mount', () => {
diff --git a/src/web/app/mobile/tags/drive.tag b/src/web/app/mobile/tags/drive.tag
index 0076dc8f4b..b5e428665a 100644
--- a/src/web/app/mobile/tags/drive.tag
+++ b/src/web/app/mobile/tags/drive.tag
@@ -172,7 +172,7 @@
 				display none
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/mobile/tags/drive/file-viewer.tag b/src/web/app/mobile/tags/drive/file-viewer.tag
index 5d06507c49..846d12d86e 100644
--- a/src/web/app/mobile/tags/drive/file-viewer.tag
+++ b/src/web/app/mobile/tags/drive/file-viewer.tag
@@ -227,7 +227,7 @@
 						background #f5f5f5
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import EXIF from 'exif-js';
 		import hljs from 'highlight.js';
 		import bytesToSize from '../../../common/scripts/bytes-to-size';
diff --git a/src/web/app/mobile/tags/drive/file.tag b/src/web/app/mobile/tags/drive/file.tag
index 03cbab2bf3..8afac79824 100644
--- a/src/web/app/mobile/tags/drive/file.tag
+++ b/src/web/app/mobile/tags/drive/file.tag
@@ -126,7 +126,7 @@
 					color #fff !important
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import bytesToSize from '../../../common/scripts/bytes-to-size';
 		this.bytesToSize = bytesToSize;
 
diff --git a/src/web/app/mobile/tags/drive/folder.tag b/src/web/app/mobile/tags/drive/folder.tag
index bb17c5e67d..2fe6c2c394 100644
--- a/src/web/app/mobile/tags/drive/folder.tag
+++ b/src/web/app/mobile/tags/drive/folder.tag
@@ -40,7 +40,7 @@
 							height 100%
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.browser = this.parent;
 		this.folder = this.opts.folder;
 
diff --git a/src/web/app/mobile/tags/follow-button.tag b/src/web/app/mobile/tags/follow-button.tag
index d96389bfce..bd4ecbaf9f 100644
--- a/src/web/app/mobile/tags/follow-button.tag
+++ b/src/web/app/mobile/tags/follow-button.tag
@@ -51,7 +51,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import isPromise from '../../common/scripts/is-promise';
 
 		this.mixin('i');
diff --git a/src/web/app/mobile/tags/home-timeline.tag b/src/web/app/mobile/tags/home-timeline.tag
index 3905e867ba..70074ef9fe 100644
--- a/src/web/app/mobile/tags/home-timeline.tag
+++ b/src/web/app/mobile/tags/home-timeline.tag
@@ -9,7 +9,7 @@
 				margin-bottom 8px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/mobile/tags/home.tag b/src/web/app/mobile/tags/home.tag
index 1bb9027ddf..a304708b3a 100644
--- a/src/web/app/mobile/tags/home.tag
+++ b/src/web/app/mobile/tags/home.tag
@@ -13,7 +13,7 @@
 				padding 16px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.on('mount', () => {
 			this.$refs.tl.on('loaded', () => {
 				this.trigger('loaded');
diff --git a/src/web/app/mobile/tags/images.tag b/src/web/app/mobile/tags/images.tag
index c39eda38b3..f4a1033117 100644
--- a/src/web/app/mobile/tags/images.tag
+++ b/src/web/app/mobile/tags/images.tag
@@ -11,7 +11,7 @@
 			@media (max-width 500px)
 				height 192px
 	</style>
-	<script>
+	<script lang="typescript">
 		this.images = this.opts.images;
 
 		this.on('mount', () => {
@@ -72,7 +72,7 @@
 				background-size cover
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.image = this.opts.image;
 		this.styles = {
 			'background-color': this.image.properties.average_color ? `rgb(${this.image.properties.average_color.join(',')})` : 'transparent',
diff --git a/src/web/app/mobile/tags/init-following.tag b/src/web/app/mobile/tags/init-following.tag
index 3eb3e14819..94949a2e25 100644
--- a/src/web/app/mobile/tags/init-following.tag
+++ b/src/web/app/mobile/tags/init-following.tag
@@ -82,7 +82,7 @@
 					padding 10px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.users = null;
diff --git a/src/web/app/mobile/tags/notification-preview.tag b/src/web/app/mobile/tags/notification-preview.tag
index a24110086d..06f4fb511a 100644
--- a/src/web/app/mobile/tags/notification-preview.tag
+++ b/src/web/app/mobile/tags/notification-preview.tag
@@ -102,7 +102,7 @@
 					color #fff
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import getPostSummary from '../../../../common/get-post-summary.ts';
 		this.getPostSummary = getPostSummary;
 		this.notification = this.opts.notification;
diff --git a/src/web/app/mobile/tags/notification.tag b/src/web/app/mobile/tags/notification.tag
index 977244e0c5..9aca50cb48 100644
--- a/src/web/app/mobile/tags/notification.tag
+++ b/src/web/app/mobile/tags/notification.tag
@@ -161,7 +161,7 @@
 					color rgba(0, 0, 0, 0.7)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import getPostSummary from '../../../../common/get-post-summary.ts';
 		this.getPostSummary = getPostSummary;
 		this.notification = this.opts.notification;
diff --git a/src/web/app/mobile/tags/notifications.tag b/src/web/app/mobile/tags/notifications.tag
index d1a6a2501d..2ff961ae21 100644
--- a/src/web/app/mobile/tags/notifications.tag
+++ b/src/web/app/mobile/tags/notifications.tag
@@ -77,7 +77,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import getPostSummary from '../../../../common/get-post-summary.ts';
 		this.getPostSummary = getPostSummary;
 
diff --git a/src/web/app/mobile/tags/notify.tag b/src/web/app/mobile/tags/notify.tag
index 787d3a374f..59d1e9dd8f 100644
--- a/src/web/app/mobile/tags/notify.tag
+++ b/src/web/app/mobile/tags/notify.tag
@@ -15,7 +15,7 @@
 			background-color rgba(#000, 0.5)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import anime from 'animejs';
 
 		this.on('mount', () => {
diff --git a/src/web/app/mobile/tags/page/drive.tag b/src/web/app/mobile/tags/page/drive.tag
index 8cc8134bc4..23185b14b8 100644
--- a/src/web/app/mobile/tags/page/drive.tag
+++ b/src/web/app/mobile/tags/page/drive.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 
diff --git a/src/web/app/mobile/tags/page/entrance.tag b/src/web/app/mobile/tags/page/entrance.tag
index b244310cfe..17ba1cd7bd 100644
--- a/src/web/app/mobile/tags/page/entrance.tag
+++ b/src/web/app/mobile/tags/page/entrance.tag
@@ -42,7 +42,7 @@
 					color rgba(#000, 0.5)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mode = 'signin';
 
 		this.signup = () => {
diff --git a/src/web/app/mobile/tags/page/home.tag b/src/web/app/mobile/tags/page/home.tag
index 4b9343a108..cf57cdb22e 100644
--- a/src/web/app/mobile/tags/page/home.tag
+++ b/src/web/app/mobile/tags/page/home.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 		import getPostSummary from '../../../../../common/get-post-summary.ts';
diff --git a/src/web/app/mobile/tags/page/messaging-room.tag b/src/web/app/mobile/tags/page/messaging-room.tag
index 4a1c57b995..67f46e4b18 100644
--- a/src/web/app/mobile/tags/page/messaging-room.tag
+++ b/src/web/app/mobile/tags/page/messaging-room.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 
 		this.mixin('api');
diff --git a/src/web/app/mobile/tags/page/messaging.tag b/src/web/app/mobile/tags/page/messaging.tag
index acde6f2693..62998c7110 100644
--- a/src/web/app/mobile/tags/page/messaging.tag
+++ b/src/web/app/mobile/tags/page/messaging.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 
 		this.mixin('page');
diff --git a/src/web/app/mobile/tags/page/notifications.tag b/src/web/app/mobile/tags/page/notifications.tag
index 97717e2e2a..eda5a19329 100644
--- a/src/web/app/mobile/tags/page/notifications.tag
+++ b/src/web/app/mobile/tags/page/notifications.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 
diff --git a/src/web/app/mobile/tags/page/post.tag b/src/web/app/mobile/tags/page/post.tag
index 296ef140c0..5e8cd24481 100644
--- a/src/web/app/mobile/tags/page/post.tag
+++ b/src/web/app/mobile/tags/page/post.tag
@@ -44,7 +44,7 @@
 						margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 
diff --git a/src/web/app/mobile/tags/page/search.tag b/src/web/app/mobile/tags/page/search.tag
index 393076367f..44af3a2ad1 100644
--- a/src/web/app/mobile/tags/page/search.tag
+++ b/src/web/app/mobile/tags/page/search.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 
diff --git a/src/web/app/mobile/tags/page/selectdrive.tag b/src/web/app/mobile/tags/page/selectdrive.tag
index ff11bad7de..b410d4603f 100644
--- a/src/web/app/mobile/tags/page/selectdrive.tag
+++ b/src/web/app/mobile/tags/page/selectdrive.tag
@@ -52,7 +52,7 @@
 				top 42px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		const q = (new URL(location)).searchParams;
 		this.multiple = q.get('multiple') == 'true' ? true : false;
 
diff --git a/src/web/app/mobile/tags/page/settings.tag b/src/web/app/mobile/tags/page/settings.tag
index beaa08b9a7..394c198b0a 100644
--- a/src/web/app/mobile/tags/page/settings.tag
+++ b/src/web/app/mobile/tags/page/settings.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 
 		this.on('mount', () => {
@@ -91,7 +91,7 @@
 							line-height $height
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import signout from '../../../common/scripts/signout';
 		this.signout = signout;
 
diff --git a/src/web/app/mobile/tags/page/settings/authorized-apps.tag b/src/web/app/mobile/tags/page/settings/authorized-apps.tag
index 0145afc622..35cc961f06 100644
--- a/src/web/app/mobile/tags/page/settings/authorized-apps.tag
+++ b/src/web/app/mobile/tags/page/settings/authorized-apps.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../../scripts/ui-event';
 
 		this.on('mount', () => {
diff --git a/src/web/app/mobile/tags/page/settings/profile.tag b/src/web/app/mobile/tags/page/settings/profile.tag
index e213f40706..cafe65f274 100644
--- a/src/web/app/mobile/tags/page/settings/profile.tag
+++ b/src/web/app/mobile/tags/page/settings/profile.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../../scripts/ui-event';
 
 		this.on('mount', () => {
@@ -169,7 +169,7 @@
 						margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('api');
 
diff --git a/src/web/app/mobile/tags/page/settings/signin.tag b/src/web/app/mobile/tags/page/settings/signin.tag
index 5c9164bcf9..7a57406c16 100644
--- a/src/web/app/mobile/tags/page/settings/signin.tag
+++ b/src/web/app/mobile/tags/page/settings/signin.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../../scripts/ui-event';
 
 		this.on('mount', () => {
diff --git a/src/web/app/mobile/tags/page/settings/twitter.tag b/src/web/app/mobile/tags/page/settings/twitter.tag
index 672eff25be..ca5fe2c43c 100644
--- a/src/web/app/mobile/tags/page/settings/twitter.tag
+++ b/src/web/app/mobile/tags/page/settings/twitter.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../../scripts/ui-event';
 
 		this.on('mount', () => {
diff --git a/src/web/app/mobile/tags/page/user-followers.tag b/src/web/app/mobile/tags/page/user-followers.tag
index 626c8025da..1123fd4224 100644
--- a/src/web/app/mobile/tags/page/user-followers.tag
+++ b/src/web/app/mobile/tags/page/user-followers.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 
diff --git a/src/web/app/mobile/tags/page/user-following.tag b/src/web/app/mobile/tags/page/user-following.tag
index 220c5fbf8c..b1c22cae1e 100644
--- a/src/web/app/mobile/tags/page/user-following.tag
+++ b/src/web/app/mobile/tags/page/user-following.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 
diff --git a/src/web/app/mobile/tags/page/user.tag b/src/web/app/mobile/tags/page/user.tag
index 04b7276364..3af11bbb4d 100644
--- a/src/web/app/mobile/tags/page/user.tag
+++ b/src/web/app/mobile/tags/page/user.tag
@@ -6,7 +6,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../../scripts/ui-event';
 		import Progress from '../../../common/scripts/loading';
 
diff --git a/src/web/app/mobile/tags/post-detail.tag b/src/web/app/mobile/tags/post-detail.tag
index 1c936a8d7b..6b70b23137 100644
--- a/src/web/app/mobile/tags/post-detail.tag
+++ b/src/web/app/mobile/tags/post-detail.tag
@@ -252,7 +252,7 @@
 					border-top 1px solid #eef0f2
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../common/scripts/text-compiler';
 		import getPostSummary from '../../../../common/get-post-summary.ts';
 		import openPostForm from '../scripts/open-post-form';
@@ -444,5 +444,5 @@
 							color #717171
 
 	</style>
-	<script>this.post = this.opts.post</script>
+	<script lang="typescript">this.post = this.opts.post</script>
 </mk-post-detail-sub>
diff --git a/src/web/app/mobile/tags/post-form.tag b/src/web/app/mobile/tags/post-form.tag
index 01c0748fea..1c0282e771 100644
--- a/src/web/app/mobile/tags/post-form.tag
+++ b/src/web/app/mobile/tags/post-form.tag
@@ -144,7 +144,7 @@
 					box-shadow none
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import Sortable from 'sortablejs';
 		import getKao from '../../common/scripts/get-kao';
 
diff --git a/src/web/app/mobile/tags/post-preview.tag b/src/web/app/mobile/tags/post-preview.tag
index 7169165879..3389bf1f05 100644
--- a/src/web/app/mobile/tags/post-preview.tag
+++ b/src/web/app/mobile/tags/post-preview.tag
@@ -90,5 +90,5 @@
 							color #717171
 
 	</style>
-	<script>this.post = this.opts.post</script>
+	<script lang="typescript">this.post = this.opts.post</script>
 </mk-post-preview>
diff --git a/src/web/app/mobile/tags/search-posts.tag b/src/web/app/mobile/tags/search-posts.tag
index 9cb5ee36f4..00936a8385 100644
--- a/src/web/app/mobile/tags/search-posts.tag
+++ b/src/web/app/mobile/tags/search-posts.tag
@@ -14,7 +14,7 @@
 				margin 16px auto
 				width calc(100% - 32px)
 	</style>
-	<script>
+	<script lang="typescript">
 		import parse from '../../common/scripts/parse-search-query';
 
 		this.mixin('api');
diff --git a/src/web/app/mobile/tags/search.tag b/src/web/app/mobile/tags/search.tag
index ab048ea132..36f375e961 100644
--- a/src/web/app/mobile/tags/search.tag
+++ b/src/web/app/mobile/tags/search.tag
@@ -4,7 +4,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.query = this.opts.query;
 
 		this.on('mount', () => {
diff --git a/src/web/app/mobile/tags/sub-post-content.tag b/src/web/app/mobile/tags/sub-post-content.tag
index 27f01fa075..211f59171c 100644
--- a/src/web/app/mobile/tags/sub-post-content.tag
+++ b/src/web/app/mobile/tags/sub-post-content.tag
@@ -27,7 +27,7 @@
 				font-size 80%
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../common/scripts/text-compiler';
 
 		this.post = this.opts.post;
diff --git a/src/web/app/mobile/tags/timeline.tag b/src/web/app/mobile/tags/timeline.tag
index bf3fa09315..47862a1267 100644
--- a/src/web/app/mobile/tags/timeline.tag
+++ b/src/web/app/mobile/tags/timeline.tag
@@ -79,7 +79,7 @@
 						opacity 0.7
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.posts = [];
 		this.init = true;
 		this.fetching = false;
@@ -456,7 +456,7 @@
 									display none
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import compile from '../../common/scripts/text-compiler';
 		import getPostSummary from '../../../../common/get-post-summary.ts';
 		import openPostForm from '../scripts/open-post-form';
@@ -684,5 +684,5 @@
 								font-size 80%
 
 	</style>
-	<script>this.post = this.opts.post</script>
+	<script lang="typescript">this.post = this.opts.post</script>
 </mk-timeline-post-sub>
diff --git a/src/web/app/mobile/tags/ui.tag b/src/web/app/mobile/tags/ui.tag
index 0c783b8f3a..16fb116eb6 100644
--- a/src/web/app/mobile/tags/ui.tag
+++ b/src/web/app/mobile/tags/ui.tag
@@ -10,7 +10,7 @@
 			display block
 			padding-top 48px
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 
 		this.mixin('stream');
@@ -144,7 +144,7 @@
 						border-left solid 1px rgba(#000, 0.1)
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import ui from '../scripts/ui-event';
 
 		this.mixin('api');
@@ -350,7 +350,7 @@
 					color #777
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 		this.mixin('page');
 		this.mixin('api');
diff --git a/src/web/app/mobile/tags/user-card.tag b/src/web/app/mobile/tags/user-card.tag
index abe46bda02..227b8b389d 100644
--- a/src/web/app/mobile/tags/user-card.tag
+++ b/src/web/app/mobile/tags/user-card.tag
@@ -49,7 +49,7 @@
 				margin 8px 0 16px 0
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.user = this.opts.user;
 	</script>
 </mk-user-card>
diff --git a/src/web/app/mobile/tags/user-followers.tag b/src/web/app/mobile/tags/user-followers.tag
index a4dc99e68a..02368045e0 100644
--- a/src/web/app/mobile/tags/user-followers.tag
+++ b/src/web/app/mobile/tags/user-followers.tag
@@ -5,7 +5,7 @@
 			display block
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
diff --git a/src/web/app/mobile/tags/user-following.tag b/src/web/app/mobile/tags/user-following.tag
index e1d98297c6..c0eb58b4be 100644
--- a/src/web/app/mobile/tags/user-following.tag
+++ b/src/web/app/mobile/tags/user-following.tag
@@ -5,7 +5,7 @@
 			display block
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
diff --git a/src/web/app/mobile/tags/user-preview.tag b/src/web/app/mobile/tags/user-preview.tag
index 498ad53ecd..ec06365e0f 100644
--- a/src/web/app/mobile/tags/user-preview.tag
+++ b/src/web/app/mobile/tags/user-preview.tag
@@ -91,5 +91,5 @@
 						color #717171
 
 	</style>
-	<script>this.user = this.opts.user</script>
+	<script lang="typescript">this.user = this.opts.user</script>
 </mk-user-preview>
diff --git a/src/web/app/mobile/tags/user-timeline.tag b/src/web/app/mobile/tags/user-timeline.tag
index dd878810cf..270a3744c3 100644
--- a/src/web/app/mobile/tags/user-timeline.tag
+++ b/src/web/app/mobile/tags/user-timeline.tag
@@ -6,7 +6,7 @@
 			max-width 600px
 			margin 0 auto
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
diff --git a/src/web/app/mobile/tags/user.tag b/src/web/app/mobile/tags/user.tag
index 316fb764e9..d0874f8e79 100644
--- a/src/web/app/mobile/tags/user.tag
+++ b/src/web/app/mobile/tags/user.tag
@@ -185,7 +185,7 @@
 						padding 16px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.age = require('s-age');
 
 		this.mixin('i');
@@ -299,7 +299,7 @@
 				color #cad2da
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 
 		this.user = this.opts.user;
@@ -341,7 +341,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
@@ -427,7 +427,7 @@
 					color #aaa
 
 	</style>
-	<script>
+	<script lang="typescript">
 		import summary from '../../../../common/get-post-summary.ts';
 
 		this.post = this.opts.post;
@@ -477,7 +477,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.images = [];
@@ -534,7 +534,7 @@
 					transform-origin center
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
@@ -586,7 +586,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.user = this.opts.user;
 	</script>
 </mk-user-overview-keywords>
@@ -620,7 +620,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.user = this.opts.user;
 	</script>
 </mk-user-overview-domains>
@@ -658,7 +658,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
@@ -713,7 +713,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.user = this.opts.user;
diff --git a/src/web/app/mobile/tags/users-list.tag b/src/web/app/mobile/tags/users-list.tag
index 17b69e9e15..fb7040a7a0 100644
--- a/src/web/app/mobile/tags/users-list.tag
+++ b/src/web/app/mobile/tags/users-list.tag
@@ -77,7 +77,7 @@
 					margin-right 4px
 
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('i');
 
 		this.limit = 30;
diff --git a/src/web/app/stats/tags/index.tag b/src/web/app/stats/tags/index.tag
index 84866c3d1b..3b2b10b0ae 100644
--- a/src/web/app/stats/tags/index.tag
+++ b/src/web/app/stats/tags/index.tag
@@ -40,7 +40,7 @@
 				> a
 					color #546567
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.initializing = true;
@@ -63,7 +63,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.initializing = true;
@@ -89,7 +89,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.mixin('api');
 
 		this.initializing = true;
@@ -142,7 +142,7 @@
 				padding 1px
 				width 100%
 	</style>
-	<script>
+	<script lang="typescript">
 		this.viewBoxX = 365;
 		this.viewBoxY = 80;
 
@@ -187,7 +187,7 @@
 				padding 1px
 				width 100%
 	</style>
-	<script>
+	<script lang="typescript">
 		this.viewBoxX = 365;
 		this.viewBoxY = 80;
 
diff --git a/src/web/app/status/tags/index.tag b/src/web/app/status/tags/index.tag
index 9ac54c867c..e06258c49e 100644
--- a/src/web/app/status/tags/index.tag
+++ b/src/web/app/status/tags/index.tag
@@ -50,7 +50,7 @@
 				> a
 					color #546567
 	</style>
-	<script>
+	<script lang="typescript">
 		import Connection from '../../common/scripts/streaming/server-stream';
 
 		this.mixin('api');
@@ -81,7 +81,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.connection = this.opts.connection;
 
 		this.on('mount', () => {
@@ -111,7 +111,7 @@
 		:scope
 			display block
 	</style>
-	<script>
+	<script lang="typescript">
 		this.connection = this.opts.connection;
 
 		this.on('mount', () => {
@@ -176,7 +176,7 @@
 				padding 1px
 				width 100%
 	</style>
-	<script>
+	<script lang="typescript">
 		import uuid from 'uuid';
 
 		this.viewBoxX = 100;