Docs
Settings Page
Settings Page This example manages a single-record settings table from the admin console. Table Create app_settings with isSingleRecord=true . Field Type Notes siteName string Public name supportEmail string Add email format rule webhookSecret string isEncrypted=true , isPublishe
Settings Page
This example manages a single-record settings table from the admin console.
Table
Create app_settings with isSingleRecord=true.
| Field | Type | Notes |
|---|---|---|
siteName |
string | Public name |
supportEmail |
string | Add email format rule |
webhookSecret |
string | isEncrypted=true, isPublished=false |
Page Extension
Use FormEditor for table-backed settings instead of hand-building every input.
<template>
<div class="space-y-4">
<FormEditorLazy
v-if="record"
table-name="app_settings"
:model-value="record"
:includes="['siteName', 'supportEmail', 'webhookSecret']"
@submit="save"
/>
<LoadingState v-else-if="pending" />
<ErrorState v-else-if="error" :error="error" />
</div>
</template>
<script setup>
const { registerPageHeader } = usePageHeaderRegistry();
registerPageHeader({
title: 'Application Settings',
description: 'Manage runtime settings',
leadingIcon: '',
variant: 'minimal'
});
const record = ref(null);
const pending = ref(false);
const error = ref(null);
const load = async () => {
pending.value = true;
error.value = null;
try {
const response = await $fetch('/api/app_settings', { query: { limit: 1 } });
record.value = response.data?.[0] || {};
} catch (err) {
error.value = err;
} finally {
pending.value = false;
}
};
const save = async (value) => {
const id = value.id || record.value?.id;
if (id) {
await $fetch(`/api/app_settings/${id}`, { method: 'PATCH', body: value });
} else {
await $fetch('/api/app_settings', { method: 'POST', body: value });
}
await load();
};
onMounted(load);
</script>
Only users with settings route permissions should see this menu item.