diff --git a/src/client/app/common/views/components/signup.vue b/src/client/app/common/views/components/signup.vue
index 1d33702159..810b850831 100644
--- a/src/client/app/common/views/components/signup.vue
+++ b/src/client/app/common/views/components/signup.vue
@@ -34,7 +34,7 @@
 			<p slot="text" v-if="passwordRetypeState == 'not-match'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@password-not-matched%</p>
 		</div>
 	</ui-input>
-	<div v-if="recaptchaSitekey != null" class="g-recaptcha" :data-sitekey="recaptchaSitekey" style="margin: 16px 0;"></div>
+	<div v-if="meta && meta.recaptchaSitekey != null" class="g-recaptcha" :data-sitekey="meta.recaptchaSitekey" style="margin: 16px 0;"></div>
 	<ui-button type="submit">%i18n:@create%</ui-button>
 </form>
 </template>
@@ -42,7 +42,7 @@
 <script lang="ts">
 import Vue from 'vue';
 const getPasswordStrength = require('syuilo-password-strength');
-import { host, url, recaptchaSitekey } from '../../../config';
+import { host, url } from '../../../config';
 
 export default Vue.extend({
 	data() {
@@ -53,7 +53,6 @@ export default Vue.extend({
 			retypedPassword: '',
 			invitationCode: '',
 			url,
-			recaptchaSitekey,
 			usernameState: null,
 			passwordStrength: '',
 			passwordRetypeState: null,
@@ -73,6 +72,12 @@ export default Vue.extend({
 			this.meta = meta;
 		});
 	},
+	mounted() {
+		const head = document.getElementsByTagName('head')[0];
+		const script = document.createElement('script');
+		script.setAttribute('src', 'https://www.google.com/recaptcha/api.js');
+		head.appendChild(script);
+	},
 	methods: {
 		onChangeUsername() {
 			if (this.username == '') {
@@ -123,7 +128,7 @@ export default Vue.extend({
 				username: this.username,
 				password: this.password,
 				invitationCode: this.invitationCode,
-				'g-recaptcha-response': recaptchaSitekey != null ? (window as any).grecaptcha.getResponse() : null
+				'g-recaptcha-response': this.meta.recaptchaSitekey != null ? (window as any).grecaptcha.getResponse() : null
 			}).then(() => {
 				(this as any).api('signin', {
 					username: this.username,
@@ -134,19 +139,11 @@ export default Vue.extend({
 			}).catch(() => {
 				alert('%i18n:@some-error%');
 
-				if (recaptchaSitekey != null) {
+				if (this.meta.recaptchaSitekey != null) {
 					(window as any).grecaptcha.reset();
 				}
 			});
 		}
-	},
-	mounted() {
-		if (recaptchaSitekey != null) {
-			const head = document.getElementsByTagName('head')[0];
-			const script = document.createElement('script');
-			script.setAttribute('src', 'https://www.google.com/recaptcha/api.js');
-			head.appendChild(script);
-		}
 	}
 });
 </script>
diff --git a/src/client/app/config.ts b/src/client/app/config.ts
index 04486ea230..76cd536a49 100644
--- a/src/client/app/config.ts
+++ b/src/client/app/config.ts
@@ -1,51 +1,22 @@
-declare const _HOST_: string;
-declare const _HOSTNAME_: string;
-declare const _URL_: string;
-declare const _NAME_: string;
-declare const _DESCRIPTION_: string;
-declare const _API_URL_: string;
-declare const _WS_URL_: string;
-declare const _DOCS_URL_: string;
-declare const _STATS_URL_: string;
-declare const _STATUS_URL_: string;
-declare const _DEV_URL_: string;
-declare const _REPOSITORY_URL_: string;
-declare const _FEEDBACK_URL_: string;
 declare const _LANG_: string;
 declare const _LANGS_: string;
-declare const _RECAPTCHA_SITEKEY_: string;
-declare const _SW_PUBLICKEY_: string;
 declare const _THEME_COLOR_: string;
 declare const _COPYRIGHT_: string;
 declare const _VERSION_: string;
 declare const _CODENAME_: string;
 declare const _LICENSE_: string;
-declare const _GOOGLE_MAPS_API_KEY_: string;
-declare const _WELCOME_BG_URL_: string;
-declare const _TWITTER_INTEGRATION_: boolean;
 
-export const host = _HOST_;
-export const hostname = _HOSTNAME_;
-export const url = _URL_;
-export const name = _NAME_;
-export const description = _DESCRIPTION_;
-export const apiUrl = _API_URL_;
-export const wsUrl = _WS_URL_;
-export const docsUrl = _DOCS_URL_;
-export const statsUrl = _STATS_URL_;
-export const statusUrl = _STATUS_URL_;
-export const devUrl = _DEV_URL_;
-export const repositoryUrl = _REPOSITORY_URL_;
-export const feedbackUrl = _FEEDBACK_URL_;
+const address = new URL(location.href);
+
+export const host = address.host;
+export const hostname = address.hostname;
+export const url = address.origin;
+export const apiUrl = url + '/api';
+export const wsUrl = url.replace('http://', 'ws://').replace('https://', 'wss://');
 export const lang = _LANG_;
 export const langs = _LANGS_;
-export const recaptchaSitekey = _RECAPTCHA_SITEKEY_;
-export const swPublickey = _SW_PUBLICKEY_;
 export const themeColor = _THEME_COLOR_;
 export const copyright = _COPYRIGHT_;
 export const version = _VERSION_;
 export const codename = _CODENAME_;
 export const license = _LICENSE_;
-export const googleMapsApiKey = _GOOGLE_MAPS_API_KEY_;
-export const welcomeBgUrl = _WELCOME_BG_URL_;
-export const twitterIntegration = _TWITTER_INTEGRATION_;
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index 000a56024d..505ff60068 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -20,6 +20,9 @@ export default () => new Promise(async (res, rej) => {
 		version: pkg.version,
 		clientVersion: client.version,
 
+		name: config.name || 'Misskey',
+		description: config.description,
+
 		secure: config.https != null,
 		machine: os.hostname(),
 		os: os.platform(),
@@ -29,6 +32,8 @@ export default () => new Promise(async (res, rej) => {
 			cores: os.cpus().length
 		},
 		broadcasts: meta.broadcasts,
-		disableRegistration: meta.disableRegistration
+		disableRegistration: meta.disableRegistration,
+		recaptchaSitekey: config.recaptcha.site_key,
+		swPublickey: config.sw.public_key
 	});
 });
diff --git a/webpack.config.ts b/webpack.config.ts
index 8dca4c0ee3..4c6da768da 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -16,7 +16,6 @@ import I18nReplacer from './src/misc/i18n';
 import { pattern as i18nPattern, replacement as i18nReplacement } from './webpack/i18n';
 import { pattern as faPattern, replacement as faReplacement } from './src/misc/fa';
 const constants = require('./src/const.json');
-import config from './src/config';
 import { licenseHtml } from './src/misc/license';
 
 const locales = require('./locales');
@@ -58,8 +57,6 @@ const isProduction = process.env.NODE_ENV == 'production';
 const entry = {
 	desktop: './src/client/app/desktop/script.ts',
 	mobile: './src/client/app/mobile/script.ts',
-	//stats: './src/client/app/stats/script.ts',
-	//status: './src/client/app/status/script.ts',
 	dev: './src/client/app/dev/script.ts',
 	auth: './src/client/app/auth/script.ts',
 	sw: './src/client/app/sw.js'
@@ -72,31 +69,13 @@ const output = {
 
 //#region Define consts
 const consts = {
-	_RECAPTCHA_SITEKEY_: config.recaptcha ? config.recaptcha.site_key : null,
-	_SW_PUBLICKEY_: config.sw ? config.sw.public_key : null,
 	_THEME_COLOR_: constants.themeColor,
 	_COPYRIGHT_: constants.copyright,
 	_VERSION_: version,
 	_CODENAME_: codename,
-	_STATUS_URL_: config.status_url,
-	_STATS_URL_: config.stats_url,
-	_DOCS_URL_: config.docs_url,
-	_API_URL_: config.api_url,
-	_WS_URL_: config.ws_url,
-	_DEV_URL_: config.dev_url,
-	_REPOSITORY_URL_: config.maintainer.repository_url,
-	_FEEDBACK_URL_: config.maintainer.feedback_url,
 	_LANG_: '%lang%',
 	_LANGS_: Object.keys(locales).map(l => [l, locales[l].meta.lang]),
-	_NAME_: config.name,
-	_DESCRIPTION_: config.description,
-	_HOST_: config.host,
-	_HOSTNAME_: config.hostname,
-	_URL_: config.url,
-	_LICENSE_: licenseHtml,
-	_GOOGLE_MAPS_API_KEY_: config.google_maps_api_key,
-	_WELCOME_BG_URL_: config.welcome_bg_url,
-	_TWITTER_INTEGRATION_: config.twitter != null
+	_LICENSE_: licenseHtml
 };
 
 const _consts: { [ key: string ]: any } = {};