diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index c68f9408ad..5dbe603e44 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -371,12 +371,35 @@ members: "メンバー"
 transfer: "譲渡"
 messagingWithUser: "ユーザーとチャット"
 messagingWithGroup: "グループでチャット"
+title: "タイトル"
+text: "テキスト"
 enable: "有効にする"
 next: "次"
 retype: "再入力"
 noteOf: "{user}のノート"
 inviteToGroup: "グループに招待"
 maxNoteTextLength: "ノートの文字数制限"
+quoteAttached: "引用付き"
+quoteQuestion: "引用として添付しますか?"
+noMessagesYet: "まだチャットはありません"
+newMessageExists: "新しいメッセージがあります"
+onlyOneFileCanBeAttached: "メッセージに添付できるファイルはひとつです"
+signinRequired: "ログインしてください"
+invitationCode: "招待コード"
+checking: "確認しています"
+available: "利用できます"
+unavailable: "利用できません"
+usernameInvalidFormat: "a~z、A~Z、0~9、_が使えます"
+tooShort: "短すぎます"
+tooLong: "長すぎます"
+weakPassword: "弱いパスワード"
+normalPassword: "普通のパスワード"
+strongPassword: "強いパスワード"
+passwordMatched: "一致しました"
+passwordNotMatched: "一致していません"
+signinWith: "{x}でログイン"
+tapSecurityKey: "セキュリティーキーにタッチ"
+or: "もしくは"
 
 _tutorial:
   title: "Misskeyの使い方"
diff --git a/src/client/components/drive.vue b/src/client/components/drive.vue
index 8a4349ae35..bb35b156aa 100644
--- a/src/client/components/drive.vue
+++ b/src/client/components/drive.vue
@@ -23,13 +23,13 @@
 				<x-folder v-for="folder in folders" :key="folder.id" class="folder" :folder="folder"/>
 				<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
 				<div class="padding" v-for="n in 16"></div>
-				<mk-button v-if="moreFolders">{{ $t('@.load-more') }}</mk-button>
+				<mk-button v-if="moreFolders">{{ $t('loadMore') }}</mk-button>
 			</div>
 			<div class="files" ref="filesContainer" v-if="files.length > 0">
 				<x-file v-for="file in files" :key="file.id" class="file" :file="file" :select-mode="selectMode"/>
 				<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
 				<div class="padding" v-for="n in 16"></div>
-				<mk-button v-if="moreFiles" @click="fetchMoreFiles">{{ $t('@.load-more') }}</mk-button>
+				<mk-button v-if="moreFiles" @click="fetchMoreFiles">{{ $t('loadMore') }}</mk-button>
 			</div>
 			<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
 				<p v-if="draghover">{{ $t('empty-draghover') }}</p>
diff --git a/src/client/components/google.vue b/src/client/components/google.vue
index e6ef7f7d90..21560008f6 100644
--- a/src/client/components/google.vue
+++ b/src/client/components/google.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="mk-google">
 	<input type="search" v-model="query" :placeholder="q">
-	<button @click="search"><fa icon="search"/> {{ $t('@.search') }}</button>
+	<button @click="search"><fa icon="search"/> {{ $t('search') }}</button>
 </div>
 </template>
 
diff --git a/src/client/components/post-form.vue b/src/client/components/post-form.vue
index 3fe14eee97..2e6285cb06 100644
--- a/src/client/components/post-form.vue
+++ b/src/client/components/post-form.vue
@@ -21,7 +21,7 @@
 	<div class="form">
 		<x-note-preview class="preview" v-if="reply" :note="reply"/>
 		<x-note-preview class="preview" v-if="renote" :note="renote"/>
-		<div class="with-quote" v-if="quoteId"><fa icon="quote-left"/> {{ $t('@.post-form.quote-attached') }}<button @click="quoteId = null"><fa icon="times"/></button></div>
+		<div class="with-quote" v-if="quoteId"><fa icon="quote-left"/> {{ $t('quoteAttached') }}<button @click="quoteId = null"><fa icon="times"/></button></div>
 		<div v-if="visibility === 'specified'" class="to-specified">
 			<span style="margin-right: 8px;">{{ $t('recipient') }}</span>
 			<div class="visibleUsers">
@@ -445,7 +445,7 @@ export default Vue.extend({
 
 				this.$root.dialog({
 					type: 'info',
-					text: this.$t('@.post-form.quote-question'),
+					text: this.$t('quoteQuestion'),
 					showCancelButton: true
 				}).then(({ canceled }) => {
 					if (canceled) {
diff --git a/src/client/components/reaction-picker.vue b/src/client/components/reaction-picker.vue
index ccf6eaa51e..9380e6a78d 100644
--- a/src/client/components/reaction-picker.vue
+++ b/src/client/components/reaction-picker.vue
@@ -13,7 +13,7 @@
 			mode="out-in"
 			appear
 		>
-			<button class="_button" v-for="(reaction, i) in rs" :key="reaction" @click="react(reaction)" :tabindex="i + 1" :title="/^[a-z]+$/.test(reaction) ? $t('@.reactions.' + reaction) : reaction"><x-reaction-icon :reaction="reaction"/></button>
+			<button class="_button" v-for="(reaction, i) in rs" :key="reaction" @click="react(reaction)" :tabindex="i + 1" :title="reaction"><x-reaction-icon :reaction="reaction"/></button>
 		</transition-group>
 		<input class="text" v-model="text" :placeholder="$t('enterEmoji')" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }">
 	</div>
diff --git a/src/client/components/signin.vue b/src/client/components/signin.vue
index 22b5ec804c..758bc59107 100644
--- a/src/client/components/signin.vue
+++ b/src/client/components/signin.vue
@@ -12,15 +12,15 @@
 			<template #prefix><fa :icon="faLock"/></template>
 		</mk-input>
 		<mk-button type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $t('loggingIn') : $t('login') }}</mk-button>
-		<p v-if="meta && meta.enableTwitterIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/twitter`"><fa :icon="['fab', 'twitter']"/> {{ $t('signin-with-twitter') }}</a></p>
-		<p v-if="meta && meta.enableGithubIntegration"  style="margin: 8px 0;"><a :href="`${apiUrl}/signin/github`"><fa :icon="['fab', 'github']"/> {{ $t('signin-with-github') }}</a></p>
-		<p v-if="meta && meta.enableDiscordIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/discord`"><fa :icon="['fab', 'discord']"/> {{ $t('signin-with-discord') /* TODO: Make these layouts better */ }}</a></p>
+		<p v-if="meta && meta.enableTwitterIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/twitter`"><fa :icon="faTwitter"/> {{ $t('signinWith', { x: 'Twitter' }) }}</a></p>
+		<p v-if="meta && meta.enableGithubIntegration"  style="margin: 8px 0;"><a :href="`${apiUrl}/signin/github`"><fa :icon="faGithub"/> {{ $t('signinWith', { x: 'GitHub' }) }}</a></p>
+		<p v-if="meta && meta.enableDiscordIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/discord`"><fa :icon="faDiscord"/> {{ $t('signinWith', { x: 'Discord' }) }}</a></p>
 	</div>
 	<div class="2fa-signin" v-if="totpLogin" :class="{ securityKeys: user && user.securityKeys }">
 		<div v-if="user && user.securityKeys" class="twofa-group tap-group">
-			<p>{{ $t('tap-key') }}</p>
+			<p>{{ $t('tapSecurityKey') }}</p>
 			<mk-button @click="queryKey" v-if="!queryingKey">
-				{{ $t('@.error.retry') }}
+				{{ $t('retry') }}
 			</mk-button>
 		</div>
 		<div class="or-hr" v-if="user && user.securityKeys">
@@ -46,6 +46,7 @@
 import Vue from 'vue';
 import { toUnicode } from 'punycode';
 import { faLock, faGavel } from '@fortawesome/free-solid-svg-icons';
+import { faTwitter, faDiscord, faGithub } from '@fortawesome/free-brands-svg-icons';
 import MkButton from './ui/button.vue';
 import MkInput from './ui/input.vue';
 import i18n from '../i18n';
@@ -86,7 +87,7 @@ export default Vue.extend({
 			credential: null,
 			challengeData: null,
 			queryingKey: false,
-			faLock, faGavel
+			faLock, faGavel, faTwitter, faDiscord, faGithub
 		};
 	},
 
diff --git a/src/client/components/signup.vue b/src/client/components/signup.vue
index 47c32a3364..b821af396c 100644
--- a/src/client/components/signup.vue
+++ b/src/client/components/signup.vue
@@ -2,9 +2,8 @@
 <form class="mk-signup" @submit.prevent="onSubmit" :autocomplete="Math.random()">
 	<template v-if="meta">
 		<mk-input v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
-			<span>{{ $t('invitation-code') }}</span>
-			<template #prefix><fa icon="id-card-alt"/></template>
-			<template #desc v-html="this.$t('invitation-info').replace('{}', 'mailto:' + meta.maintainerEmail)"></template>
+			<span>{{ $t('invitationCode') }}</span>
+			<template #prefix><fa :icon="faKey"/></template>
 		</mk-input>
 		<mk-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername">
 			<span>{{ $t('username') }}</span>
@@ -15,26 +14,26 @@
 				<span v-if="usernameState == 'ok'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('available') }}</span>
 				<span v-if="usernameState == 'unavailable'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('unavailable') }}</span>
 				<span v-if="usernameState == 'error'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('error') }}</span>
-				<span v-if="usernameState == 'invalid-format'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('invalid-format') }}</span>
-				<span v-if="usernameState == 'min-range'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('too-short') }}</span>
-				<span v-if="usernameState == 'max-range'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('too-long') }}</span>
+				<span v-if="usernameState == 'invalid-format'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('usernameInvalidFormat') }}</span>
+				<span v-if="usernameState == 'min-range'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('tooShort') }}</span>
+				<span v-if="usernameState == 'max-range'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('tooLong') }}</span>
 			</template>
 		</mk-input>
 		<mk-input v-model="password" type="password" :autocomplete="Math.random()" required @input="onChangePassword">
 			<span>{{ $t('password') }}</span>
 			<template #prefix><fa :icon="faLock"/></template>
 			<template #desc>
-				<p v-if="passwordStrength == 'low'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('weak-password') }}</p>
-				<p v-if="passwordStrength == 'medium'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('normal-password') }}</p>
-				<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('strong-password') }}</p>
+				<p v-if="passwordStrength == 'low'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('weakPassword') }}</p>
+				<p v-if="passwordStrength == 'medium'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('normalPassword') }}</p>
+				<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('strongPassword') }}</p>
 			</template>
 		</mk-input>
 		<mk-input v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @input="onChangePasswordRetype">
 			<span>{{ $t('password') }} ({{ $t('retype') }})</span>
 			<template #prefix><fa :icon="faLock"/></template>
 			<template #desc>
-				<p v-if="passwordRetypeState == 'match'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('password-matched') }}</p>
-				<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('password-not-matched') }}</p>
+				<p v-if="passwordRetypeState == 'match'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('passwordMatched') }}</p>
+				<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('passwordNotMatched') }}</p>
 			</template>
 		</mk-input>
 		<mk-switch v-model="ToSAgreement" v-if="meta.tosUrl">
@@ -50,7 +49,7 @@
 
 <script lang="ts">
 import Vue from 'vue';
-import { faLock, faExclamationTriangle, faSpinner, faCheck } from '@fortawesome/free-solid-svg-icons';
+import { faLock, faExclamationTriangle, faSpinner, faCheck, faKey } from '@fortawesome/free-solid-svg-icons';
 const getPasswordStrength = require('syuilo-password-strength');
 import { toUnicode } from 'punycode';
 import i18n from '../i18n';
@@ -81,7 +80,7 @@ export default Vue.extend({
 			passwordRetypeState: null,
 			submitting: false,
 			ToSAgreement: false,
-			faLock, faExclamationTriangle, faSpinner, faCheck
+			faLock, faExclamationTriangle, faSpinner, faCheck, faKey
 		}
 	},
 
@@ -175,7 +174,7 @@ export default Vue.extend({
 
 				this.$root.dialog({
 					type: 'error',
-					text: this.$t('some-error')
+					text: this.$t('error')
 				});
 
 				if (this.meta.enableRecaptcha) {
diff --git a/src/client/components/time.vue b/src/client/components/time.vue
index 922067b4d5..6d092cf4f8 100644
--- a/src/client/components/time.vue
+++ b/src/client/components/time.vue
@@ -48,7 +48,7 @@ export default Vue.extend({
 				ago >= 10       ? this.$t('_ago.secondsAgo', { n: (~~(ago % 60)).toString() }) :
 				ago >= -1       ? this.$t('_ago.justNow') :
 				ago <  -1       ? this.$t('_ago.future') :
-				this.$t('@.time.unknown'));
+				this.$t('_ago.unknown'));
 		}
 	},
 	created() {
diff --git a/src/client/components/user-list.vue b/src/client/components/user-list.vue
index a0c16266eb..dbd00f7fbb 100644
--- a/src/client/components/user-list.vue
+++ b/src/client/components/user-list.vue
@@ -23,7 +23,7 @@
 			<mk-follow-button class="koudoku-button" v-if="$store.getters.isSignedIn && user.id != $store.state.i.id" :user="user" mini/>
 		</div>
 		<button class="more" :class="{ fetching: moreFetching }" v-if="more" @click="fetchMore()" :disabled="moreFetching">
-			<template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template>{{ moreFetching ? $t('@.loading') : $t('@.load-more') }}
+			<template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template>{{ moreFetching ? $t('loading') : $t('loadMore') }}
 		</button>
 	</div>
 </mk-container>
diff --git a/src/client/pages/instance/index.vue b/src/client/pages/instance/index.vue
index 6ffdec2a65..136a27e4a6 100644
--- a/src/client/pages/instance/index.vue
+++ b/src/client/pages/instance/index.vue
@@ -43,8 +43,8 @@
 		<div class="_content">
 			<mk-switch v-model="enableRecaptcha">{{ $t('enableRecaptcha') }}</mk-switch>
 			<template v-if="enableRecaptcha">
-				<mk-info>{{ $t('recaptcha-info') }}</mk-info>
-				<mk-info warn>{{ $t('recaptcha-info2') }}</mk-info>
+				<mk-info>{{ $t('recaptchaInfo') }}</mk-info>
+				<mk-info warn>{{ $t('recaptchaInfo2') }}</mk-info>
 				<mk-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa :icon="faKey"/></template>{{ $t('recaptchaSiteKey') }}</mk-input>
 				<mk-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa :icon="faKey"/></template>{{ $t('recaptchaSecretKey') }}</mk-input>
 			</template>
@@ -61,12 +61,12 @@
 	<section class="_card">
 		<div class="_title"><fa :icon="faBolt"/> {{ $t('serviceworker') }}</div>
 		<div class="_content">
-			<mk-switch v-model="enableServiceWorker">{{ $t('enableServiceworker') }}<template #desc>{{ $t('serviceworker-info') }}</template></mk-switch>
+			<mk-switch v-model="enableServiceWorker">{{ $t('enableServiceworker') }}<template #desc>{{ $t('serviceworkerInfo') }}</template></mk-switch>
 			<template v-if="enableServiceWorker">
-				<mk-info>{{ $t('vapid-info') }}<br><code>npm i web-push -g<br>web-push generate-vapid-keys</code></mk-info>
+				<mk-info>{{ $t('vapidInfo') }}<br><code>npx web-push generate-vapid-keys</code></mk-info>
 				<mk-horizon-group inputs class="fit-bottom">
-					<mk-input v-model="swPublicKey" :disabled="!enableServiceWorker"><template #icon><fa :icon="faKey"/></template>{{ $t('vapid-publickey') }}</mk-input>
-					<mk-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa :icon="faKey"/></template>{{ $t('vapid-privatekey') }}</mk-input>
+					<mk-input v-model="swPublicKey" :disabled="!enableServiceWorker"><template #icon><fa :icon="faKey"/></template>Public key</mk-input>
+					<mk-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa :icon="faKey"/></template>Private key</mk-input>
 				</mk-horizon-group>
 			</template>
 		</div>
diff --git a/src/client/pages/messaging-room.form.vue b/src/client/pages/messaging-room.form.vue
index 282451c7fd..14659fb1c4 100644
--- a/src/client/pages/messaging-room.form.vue
+++ b/src/client/pages/messaging-room.form.vue
@@ -100,7 +100,7 @@ export default Vue.extend({
 					const formatted = `${formatTimeString(new Date(file.lastModified), this.$store.state.settings.pastedFileName).replace(/{{number}}/g, '1')}${ext}`;
 					const name = this.$store.state.settings.pasteDialog
 						? await this.$root.dialog({
-							title: this.$t('@.post-form.enter-file-name'),
+							title: this.$t('enterFileName'),
 							input: {
 								default: formatted
 							},
diff --git a/src/client/pages/messaging-room.message.vue b/src/client/pages/messaging-room.message.vue
index 55c200cf46..bfb6b73ad8 100644
--- a/src/client/pages/messaging-room.message.vue
+++ b/src/client/pages/messaging-room.message.vue
@@ -3,7 +3,7 @@
 	<mk-avatar class="avatar" :user="message.user"/>
 	<div class="content">
 		<div class="balloon _panel" :data-no-text="message.text == null">
-			<button class="delete-button" v-if="isMe" :title="$t('@.delete')" @click="del">
+			<button class="delete-button" v-if="isMe" :title="$t('delete')" @click="del">
 				<img src="/assets/desktop/remove.png" alt="Delete"/>
 			</button>
 			<div class="content" v-if="!message.isDeleted">
diff --git a/src/client/pages/messaging-room.vue b/src/client/pages/messaging-room.vue
index 39f8831ade..b2584393a0 100644
--- a/src/client/pages/messaging-room.vue
+++ b/src/client/pages/messaging-room.vue
@@ -14,10 +14,10 @@
 
 	<div class="body">
 		<mk-loading v-if="fetching"/>
-		<p class="empty" v-if="!fetching && messages.length == 0"><fa icon="info-circle"/>{{ user ? $t('not-talked-user') : $t('not-talked-group') }}</p>
+		<p class="empty" v-if="!fetching && messages.length == 0"><fa :icon="faInfoCircle"/>{{ $t('noMessagesYet') }}</p>
 		<p class="no-history" v-if="!fetching && messages.length > 0 && !existMoreMessages"><fa :icon="faFlag"/>{{ $t('noMoreHistory') }}</p>
 		<button class="more _button" :class="{ fetching: fetchingMoreMessages }" v-if="existMoreMessages" @click="fetchMoreMessages" :disabled="fetchingMoreMessages">
-			<template v-if="fetchingMoreMessages"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreMessages ? $t('@.loading') : $t('@.load-more') }}
+			<template v-if="fetchingMoreMessages"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreMessages ? $t('loading') : $t('loadMore') }}
 		</button>
 		<x-list class="messages" :items="messages" v-slot="{ item: message, i }" direction="up" reversed>
 			<x-message :message="message" :is-group="group != null" :key="message.id"/>
@@ -26,7 +26,7 @@
 	<footer>
 		<transition name="fade">
 			<div class="new-message" v-show="showIndicator">
-				<button class="_buttonPrimary" @click="onIndicatorClick"><i><fa :icon="faArrowCircleDown"/></i>{{ $t('new-message') }}</button>
+				<button class="_buttonPrimary" @click="onIndicatorClick"><i><fa :icon="faArrowCircleDown"/></i>{{ $t('newMessageExists') }}</button>
 			</div>
 		</transition>
 		<x-form v-if="!fetching" :user="user" :group="group" ref="form"/>
@@ -36,7 +36,7 @@
 
 <script lang="ts">
 import Vue from 'vue';
-import { faArrowCircleDown, faFlag, faUsers } from '@fortawesome/free-solid-svg-icons';
+import { faArrowCircleDown, faFlag, faUsers, faInfoCircle } from '@fortawesome/free-solid-svg-icons';
 import i18n from '../i18n';
 import XList from '../components/date-separated-list.vue';
 import XMessage from './messaging-room.message.vue';
@@ -64,7 +64,7 @@ export default Vue.extend({
 			connection: null,
 			showIndicator: false,
 			timer: null,
-			faArrowCircleDown, faFlag, faUsers
+			faArrowCircleDown, faFlag, faUsers, faInfoCircle
 		};
 	},
 
@@ -139,7 +139,7 @@ export default Vue.extend({
 			} else if (e.dataTransfer.files.length > 1) {
 				this.$root.dialog({
 					type: 'error',
-					text: this.$t('only-one-file-attached')
+					text: this.$t('onlyOneFileCanBeAttached')
 				});
 				return;
 			}
diff --git a/src/client/scripts/please-login.ts b/src/client/scripts/please-login.ts
index 7125541bb1..ebd7dd82ab 100644
--- a/src/client/scripts/please-login.ts
+++ b/src/client/scripts/please-login.ts
@@ -2,7 +2,7 @@ export default ($root: any) => {
 	if ($root.$store.getters.isSignedIn) return;
 
 	$root.dialog({
-		title: $root.$t('@.signin-required'),
+		title: $root.$t('signinRequired'),
 		text: null
 	});