diff --git a/src/web/app/common/define-widget.ts b/src/web/app/common/define-widget.ts
index 826f9cc636..21821629ad 100644
--- a/src/web/app/common/define-widget.ts
+++ b/src/web/app/common/define-widget.ts
@@ -34,19 +34,20 @@ export default function<T extends object>(data: {
 			}
 
 			this.$watch('props', newProps => {
+				const w = (this as any).os.i.client_settings.mobile_home.find(w => w.id == this.id);
 				if (this.isMobile) {
 					(this as any).api('i/update_mobile_home', {
 						id: this.id,
 						data: newProps
 					}).then(() => {
-						(this as any).os.i.client_settings.mobile_home.find(w => w.id == this.id).data = newProps;
+						w.data = newProps;
 					});
 				} else {
 					(this as any).api('i/update_home', {
 						id: this.id,
 						data: newProps
 					}).then(() => {
-						(this as any).os.i.client_settings.home.find(w => w.id == this.id).data = newProps;
+						w.data = newProps;
 					});
 				}
 			}, {
diff --git a/src/web/app/common/views/components/index.ts b/src/web/app/common/views/components/index.ts
index e66a323266..5460d75779 100644
--- a/src/web/app/common/views/components/index.ts
+++ b/src/web/app/common/views/components/index.ts
@@ -25,7 +25,6 @@ import fileTypeIcon from './file-type-icon.vue';
 import wAccessLog from './widgets/access-log.vue';
 import wVersion from './widgets/version.vue';
 import wRss from './widgets/rss.vue';
-import wProfile from './widgets/profile.vue';
 import wServer from './widgets/server.vue';
 import wBroadcast from './widgets/broadcast.vue';
 import wCalendar from './widgets/calendar.vue';
@@ -65,7 +64,6 @@ Vue.component('mkw-slideshow', wSlideshow);
 Vue.component('mkw-tips', wTips);
 Vue.component('mkw-donation', wDonation);
 Vue.component('mkw-broadcast', wBroadcast);
-Vue.component('mkw-profile', wProfile);
 Vue.component('mkw-server', wServer);
 Vue.component('mkw-rss', wRss);
 Vue.component('mkw-version', wVersion);
diff --git a/src/web/app/common/views/components/widgets/profile.vue b/src/web/app/desktop/views/components/widgets/profile.vue
similarity index 100%
rename from src/web/app/common/views/components/widgets/profile.vue
rename to src/web/app/desktop/views/components/widgets/profile.vue
diff --git a/src/web/app/mobile/views/components/index.ts b/src/web/app/mobile/views/components/index.ts
index d372f22332..ea2349802b 100644
--- a/src/web/app/mobile/views/components/index.ts
+++ b/src/web/app/mobile/views/components/index.ts
@@ -23,6 +23,7 @@ import widgetContainer from './widget-container.vue';
 
 //#region widgets
 import wActivity from './widgets/activity.vue';
+import wProfile from './widgets/profile.vue';
 //#endregion
 
 Vue.component('mk-ui', ui);
@@ -48,4 +49,5 @@ Vue.component('mk-widget-container', widgetContainer);
 
 //#region widgets
 Vue.component('mkw-activity', wActivity);
+Vue.component('mkw-profile', wProfile);
 //#endregion
diff --git a/src/web/app/mobile/views/components/widgets/profile.vue b/src/web/app/mobile/views/components/widgets/profile.vue
new file mode 100644
index 0000000000..9336068e57
--- /dev/null
+++ b/src/web/app/mobile/views/components/widgets/profile.vue
@@ -0,0 +1,62 @@
+<template>
+<div class="mkw-profile">
+	<mk-widget-container>
+		<div :class="$style.banner"
+			:style="os.i.banner_url ? `background-image: url(${os.i.banner_url}?thumbnail&size=256)` : ''"
+		></div>
+		<img :class="$style.avatar"
+			:src="`${os.i.avatar_url}?thumbnail&size=96`"
+			alt="avatar"
+		/>
+		<router-link :class="$style.name" :to="`/${os.i.username}`">{{ os.i.name }}</router-link>
+	</mk-widget-container>
+</div>
+</template>
+
+<script lang="ts">
+import define from '../../../../common/define-widget';
+export default define({
+	name: 'profile'
+});
+</script>
+
+<style lang="stylus" module>
+.banner
+	height 100px
+	background-color #f5f5f5
+	background-size cover
+	background-position center
+	cursor pointer
+
+.banner:before
+	content ""
+	display block
+	width 100%
+	height 100%
+	background rgba(0, 0, 0, 0.5)
+
+.avatar
+	display block
+	position absolute
+	width 58px
+	height 58px
+	margin 0
+	vertical-align bottom
+	top ((100px - 58px) / 2)
+	left ((100px - 58px) / 2)
+	border none
+	border-radius 100%
+	box-shadow 0 0 16px rgba(0, 0, 0, 0.5)
+
+.name
+	display block
+	position absolute
+	top 0
+	left 92px
+	margin 0
+	line-height 100px
+	color #fff
+	font-weight bold
+	text-shadow 0 0 8px rgba(0, 0, 0, 0.5)
+
+</style>