diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.button.vue b/packages/client/src/pages/page-editor/els/page-editor.el.button.vue
index 827679d6a..4c2e0e4eb 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.button.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.button.vue
@@ -38,44 +38,28 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkSelect from '@/components/form/select.vue';
 import MkInput from '@/components/form/input.vue';
 import MkSwitch from '@/components/form/switch.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkSelect, MkInput, MkSwitch
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-		hpml: {
-			required: true,
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.text == null) this.value.text = '';
-		if (this.value.action == null) this.value.action = 'dialog';
-		if (this.value.content == null) this.value.content = null;
-		if (this.value.event == null) this.value.event = null;
-		if (this.value.message == null) this.value.message = null;
-		if (this.value.primary == null) this.value.primary = false;
-		if (this.value.var == null) this.value.var = null;
-		if (this.value.fn == null) this.value.fn = null;
-	},
+withDefaults(defineProps<{
+	value: any,
+	hpml: any
+}>(), {
+	value: {
+		text: '',
+		action: 'dialog',
+		content: null,
+		event: null,
+		message: null,
+		primary: false,
+		var: null,
+		fn: null
+	}
 });
 </script>
 
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.canvas.vue b/packages/client/src/pages/page-editor/els/page-editor.el.canvas.vue
index ba5d0ba1f..191321ae1 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.canvas.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.canvas.vue
@@ -20,33 +20,19 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkInput from '@/components/form/input.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkInput
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.name == null) this.value.name = '';
-		if (this.value.width == null) this.value.width = 300;
-		if (this.value.height == null) this.value.height = 200;
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		name: '',
+		width: 300,
+		height: 200
+	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue b/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue
index dc98a610b..1a2078448 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue
@@ -18,31 +18,17 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkInput from '@/components/form/input.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkInput
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.name == null) this.value.name = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		name: ''
+	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.if.vue b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
index be3a520ea..d763070b1 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
@@ -25,54 +25,39 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent, defineAsyncComponent } from 'vue';
+import { defineAsyncComponent, inject } from 'vue';
 import { v4 as uuid } from 'uuid';
 import XContainer from '../page-editor.container.vue';
 import MkSelect from '@/components/form/select.vue';
 import * as os from '@/os';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	components: {
-		XContainer, MkSelect,
-		XBlocks: defineAsyncComponent(() => import('../page-editor.blocks.vue')),
-	},
+const XBlocks = defineAsyncComponent(() => import('../page-editor.blocks.vue'));
 
-	inject: ['getPageBlockList'],
-
-	props: {
-		value: {
-			required: true
-		},
-		hpml: {
-			required: true,
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.children == null) this.value.children = [];
-		if (this.value.var === undefined) this.value.var = null;
-	},
-
-	methods: {
-		async add() {
-			const { canceled, result: type } = await os.select({
-				title: this.$ts._pages.chooseBlock,
-				groupedItems: this.getPageBlockList()
-			});
-			if (canceled) return;
-
-			const id = uuid();
-			this.value.children.push({ id, type });
-		},
+const props = withDefaults(defineProps<{
+	value: any,
+	hpml: any
+}>(), {
+	value: {
+		children: [],
+		var: null
 	}
 });
+
+const getPageBlockList = inject<(any) => any>('getPageBlockList');
+
+async function add() {
+	const { canceled, result: type } = await os.select({
+		title: i18n.ts._pages.chooseBlock,
+		groupedItems: getPageBlockList()
+	});
+	if (canceled) return;
+
+	const id = uuid();
+	props.value.children.push({ id, type });
+}
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.image.vue b/packages/client/src/pages/page-editor/els/page-editor.el.image.vue
index 9a6adab30..b22bf1cb3 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.image.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.image.vue
@@ -14,53 +14,39 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { onMounted } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkDriveFileThumbnail from '@/components/drive-file-thumbnail.vue';
 import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkDriveFileThumbnail
-	},
+const props = withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		fileId: null
+	}
+});
 
-	props: {
-		value: {
-			required: true
-		},
-	},
+let file: any = $ref(null);
 
-	data() {
-		return {
-			file: null,
-		};
-	},
+async function choose() {
+	os.selectDriveFile(false).then((fileResponse: any) => {
+		file = fileResponse;
+		props.value.fileId = fileResponse.id;
+	});
+}
 
-	created() {
-		if (this.value.fileId === undefined) this.value.fileId = null;
-	},
-
-	mounted() {
-		if (this.value.fileId == null) {
-			this.choose();
-		} else {
-			os.api('drive/files/show', {
-				fileId: this.value.fileId
-			}).then(file => {
-				this.file = file;
-			});
-		}
-	},
-
-	methods: {
-		async choose() {
-			os.selectDriveFile(false).then(file => {
-				this.file = file;
-				this.value.fileId = file.id;
-			});
-		},
+onMounted(async () => {
+	if (props.value.fileId == null) {
+		await choose();
+	} else {
+		os.api('drive/files/show', {
+			fileId: props.value.fileId
+		}).then(fileResponse => {
+			file = fileResponse;
+		});
 	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.note.vue b/packages/client/src/pages/page-editor/els/page-editor.el.note.vue
index 2d4d9c5dc..27f9f961f 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.note.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.note.vue
@@ -16,9 +16,9 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { watch } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkInput from '@/components/form/input.vue';
 import MkSwitch from '@/components/form/switch.vue';
@@ -26,42 +26,27 @@ import XNote from '@/components/note.vue';
 import XNoteDetailed from '@/components/note-detailed.vue';
 import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkInput, MkSwitch, XNote, XNoteDetailed,
-	},
+const props = withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		note: null,
+		detailed: false
+	}
+});
 
-	props: {
-		value: {
-			required: true
-		},
-	},
+let id: any = $ref(props.value.note);
+let note: any = $ref(null);
 
-	data() {
-		return {
-			id: this.value.note,
-			note: null,
-		};
-	},
+watch(id, async () => {
+	if (id && (id.startsWith('http://') || id.startsWith('https://'))) {
+		props.value.note = (id.endsWith('/') ? id.slice(0, -1) : id).split('/').pop();
+	} else {
+		props.value.note = id;
+	}
 
-	watch: {
-		id: {
-			async handler() {
-				if (this.id && (this.id.startsWith('http://') || this.id.startsWith('https://'))) {
-					this.value.note = this.id.endsWith('/') ? this.id.substr(0, this.id.length - 1).split('/').pop() : this.id.split('/').pop();
-				} else {
-					this.value.note = this.id;
-				}
-
-				this.note = await os.api('notes/show', { noteId: this.value.note });
-			},
-			immediate: true
-		},
-	},
-
-	created() {
-		if (this.value.note == null) this.value.note = null;
-		if (this.value.detailed == null) this.value.detailed = false;
-	},
+	note = await os.api('notes/show', { noteId: props.value.note });
+}, {
+	immediate: true
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue
index 9083f0c49..479a859e7 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue
@@ -18,31 +18,17 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkInput from '@/components/form/input.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkInput
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.name == null) this.value.name = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		name: ''
+	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.post.vue b/packages/client/src/pages/page-editor/els/page-editor.el.post.vue
index 3af720f4b..f8c42c296 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.post.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.post.vue
@@ -11,35 +11,21 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkTextarea from '@/components/form/textarea.vue';
 import MkInput from '@/components/form/input.vue';
 import MkSwitch from '@/components/form/switch.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkTextarea, MkInput, MkSwitch
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.text == null) this.value.text = '';
-		if (this.value.attachCanvasImage == null) this.value.attachCanvasImage = false;
-		if (this.value.canvasId == null) this.value.canvasId = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		text: '',
+		attachCanvasImage: false,
+		canvasId: ''
+	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
index 2502a54d7..183e60a69 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
@@ -12,41 +12,28 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { watch } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkTextarea from '@/components/form/textarea.vue';
 import MkInput from '@/components/form/input.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkTextarea, MkInput
-	},
-	props: {
-		value: {
-			required: true
-		},
-	},
-	data() {
-		return {
-			values: '',
-		};
-	},
-	watch: {
-		values: {
-			handler() {
-				this.value.values = this.values.split('\n');
-			},
-			deep: true
-		}
-	},
-	created() {
-		if (this.value.name == null) this.value.name = '';
-		if (this.value.title == null) this.value.title = '';
-		if (this.value.values == null) this.value.values = [];
-		this.values = this.value.values.join('\n');
-	},
+const props = withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		name: '',
+		title: '',
+		values: []
+	}
+});
+
+let values: string = $ref(props.value.values.join('\n'));
+
+watch(values, () => {
+	props.value.values = values.split('\n')
+}, {
+	deep: true
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.section.vue b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
index 1684895fe..7276cc1e1 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
@@ -17,66 +17,51 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent, defineAsyncComponent } from 'vue';
+import { defineAsyncComponent, inject, onMounted } from 'vue';
 import { v4 as uuid } from 'uuid';
 import XContainer from '../page-editor.container.vue';
 import * as os from '@/os';
+import { i18n } from '@/i18n';
 
-export default defineComponent({
-	components: {
-		XContainer,
-		XBlocks: defineAsyncComponent(() => import('../page-editor.blocks.vue')),
-	},
+const XBlocks = defineAsyncComponent(() => import('../page-editor.blocks.vue'));
 
-	inject: ['getPageBlockList'],
+const props = withDefaults(defineProps<{
+	value: any,
+	hpml: any
+}>(), {
+	value: {
+		title: null,
+		children: []
+	}
+});
 
-	props: {
-		value: {
-			required: true
-		},
-		hpml: {
-			required: true,
-		},
-	},
+const getPageBlockList = inject<(any) => any>('getPageBlockList');
 
-	data() {
-		return {
-		};
-	},
+async function rename() {
+	const { canceled, result: title } = await os.inputText({
+		title: 'Enter title',
+		default: props.value.title
+	});
+	if (canceled) return;
+	props.value.title = title;
+}
 
-	created() {
-		if (this.value.title == null) this.value.title = null;
-		if (this.value.children == null) this.value.children = [];
-	},
+async function add() {
+	const { canceled, result: type } = await os.select({
+		title: i18n.ts._pages.chooseBlock,
+		groupedItems: getPageBlockList()
+	});
+	if (canceled) return;
 
-	mounted() {
-		if (this.value.title == null) {
-			this.rename();
-		}
-	},
+	const id = uuid();
+	props.value.children.push({ id, type });
+}
 
-	methods: {
-		async rename() {
-			const { canceled, result: title } = await os.inputText({
-				title: 'Enter title',
-				default: this.value.title
-			});
-			if (canceled) return;
-			this.value.title = title;
-		},
-
-		async add() {
-			const { canceled, result: type } = await os.select({
-				title: this.$ts._pages.chooseBlock,
-				groupedItems: this.getPageBlockList()
-			});
-			if (canceled) return;
-
-			const id = uuid();
-			this.value.children.push({ id, type });
-		},
+onMounted(() => {
+	if (props.value.title == null) {
+		rename();
 	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue b/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue
index b989dce0a..ded57cf30 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue
@@ -11,33 +11,19 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkSwitch from '@/components/form/switch.vue';
 import MkInput from '@/components/form/input.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkSwitch, MkInput
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.name == null) this.value.name = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		name: ''
+	}
 });
 </script>
 
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue
index b25ac38d5..1e269ae58 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue
@@ -11,31 +11,17 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkInput from '@/components/form/input.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkInput
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.name == null) this.value.name = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		name: ''
+	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.text.vue b/packages/client/src/pages/page-editor/els/page-editor.el.text.vue
index f23a8ded9..e0ebe68dd 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.text.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.text.vue
@@ -9,31 +9,17 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.text == null) this.value.text = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		text: ''
+	}
 });
 </script>
 
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue
index f61f0cb1b..1bb4aaa54 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue
@@ -11,32 +11,18 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
 import MkTextarea from '@/components/form/textarea.vue';
 import MkInput from '@/components/form/input.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer, MkTextarea, MkInput
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.name == null) this.value.name = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		name: ''
+	}
 });
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue b/packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue
index bbabe2848..dca7de8df 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue
@@ -9,31 +9,17 @@
 </XContainer>
 </template>
 
-<script lang="ts">
+<script lang="ts" setup>
 /* eslint-disable vue/no-mutating-props */
-import { defineComponent } from 'vue';
+import { } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import * as os from '@/os';
 
-export default defineComponent({
-	components: {
-		XContainer
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-	},
-
-	data() {
-		return {
-		};
-	},
-
-	created() {
-		if (this.value.text == null) this.value.text = '';
-	},
+withDefaults(defineProps<{
+	value: any
+}>(), {
+	value: {
+		text: ''
+	}
 });
 </script>