Settings Pages
Full settings screens — personal account settings with anchored section navigation and server-ready forms, and organization settings with a side-column section nav.
Preview
{{--
Settings Page 01 — a full account-settings screen that composes the
settings-* blocks behind a sticky section nav. No JS: the nav is anchor
links to each section (scroll-mt keeps headings clear of the viewport top),
so it is robust and fully accessible. Swap or reorder the <section>s to fit
your app; each wraps a single installed settings block.
--}}
@props([
'profileHref' => '#',
'actions' => null,
'billingLinks' => null,
'statusMessage' => null,
])
@php
$actions ??= [
'profile' => '#',
'billing' => '#',
'security' => '#',
'notifications' => '#',
'integrations' => '#',
];
$billingLinks ??= ['upgrade' => '#', 'cancel' => '#', 'payment' => '#'];
@endphp
<main id="main-content" data-visual-contracts="VC-010">
<x-ui.form.guard
data-slot="page-settings"
class="mx-auto w-full max-w-5xl px-4 py-8 sm:px-6 lg:px-8"
>
<header class="mb-8 flex flex-wrap items-end justify-between gap-4">
<div>
<h1 class="text-2xl font-semibold tracking-tight text-foreground">{{ __('Settings') }}</h1>
<p class="mt-2 text-sm text-muted-foreground">{{ __('Manage your profile, billing, security, notifications and integrations.') }}</p>
</div>
<x-ui.button :href="$profileHref" variant="outline">{{ __('View profile') }}</x-ui.button>
</header>
@if ($statusMessage)
<x-ui.alert variant="success" role="status" class="mb-6">{{ __($statusMessage) }}</x-ui.alert>
@endif
<div class="grid gap-8 lg:grid-cols-[12rem_minmax(0,1fr)]">
<nav class="min-w-0 lg:sticky lg:top-8 lg:self-start" aria-label="{{ __('Settings sections') }}">
<ul class="flex w-full max-w-full gap-2 overflow-x-auto pb-2 lg:flex-col lg:gap-0.5 lg:overflow-visible lg:pb-0">
@foreach ([
'profile' => 'Profile',
'billing' => 'Billing',
'security' => 'Security',
'notifications' => 'Notifications',
'integrations' => 'Integrations',
] as $anchor => $label)
<li>
<a
href="#{{ $anchor }}"
class="block whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>{{ __($label) }}</a>
</li>
@endforeach
</ul>
</nav>
<div class="min-w-0 space-y-12">
<section id="profile" class="scroll-mt-8" aria-label="{{ __('Profile') }}">
<x-blocks.settings-account :action="$actions['profile'] ?? '#'" />
</section>
<section id="billing" class="scroll-mt-8" aria-label="{{ __('Billing') }}">
<x-blocks.settings-billing
:upgrade-href="$billingLinks['upgrade'] ?? '#'"
:cancel-href="$billingLinks['cancel'] ?? '#'"
:payment-href="$billingLinks['payment'] ?? '#'"
/>
</section>
<section id="security" class="scroll-mt-8" aria-label="{{ __('Security') }}">
<x-blocks.settings-security :action="$actions['security'] ?? '#'" />
</section>
<section id="notifications" class="scroll-mt-8" aria-label="{{ __('Notifications') }}">
<x-blocks.settings-notifications :action="$actions['notifications'] ?? '#'" />
</section>
<section id="integrations" class="scroll-mt-8" aria-label="{{ __('Integrations') }}">
<x-blocks.settings-integrations :action="$actions['integrations'] ?? '#'" />
</section>
</div>
</div>
</x-ui.form.guard>
</main>
Installation
php artisan ui:add pages/settings-page
Registry contract
Install confidence
php artisan ui:add pages/settings-page
writes only the generated targets below. The CLI validates each file hash before writing and
prompts before replacing local changes unless --force is used.
- Version
- 1.3.4
- License
- open
- Stability
- stable
- Contract
- v2
- Foundation
- ≥ 1.0.0
| Type | Generated target |
|---|---|
| blade | resources/views/pages/settings-page.blade.php |
Registry dependencies
Package dependencies
composer: jml/brok:^0.2
Use with AI
A brief for your coding agent: what the page is, the install command, how to render it, its props and the rules. Copy it, or open a prompt about this page in an assistant.
# Brok UI page: Settings Page (`settings-page`)
A server-ready account-settings screen with section endpoints, billing links, success feedback, submit locking, unsaved-change protection, and responsive anchored navigation.
Brok UI is a Laravel Blade registry. `ui:add` copies this page into the app as plain Blade the app owns; it composes installed `<brok:*>` primitives and semantic design tokens.
## Install
```bash
php artisan ui:add pages/settings-page
```
## Render it
```blade
<x-pages.settings-page />
```
## Props
- `profile-href` (string, default `#`) — Profile page destination.
- `actions` (array|null, default `null`) — Profile, security, notification, and integration endpoints by section key.
- `billing-links` (array|null, default `null`) — Upgrade, cancel, and payment destinations.
- `status-message` (string|null, default `null`) — Success feedback after a section redirect.
## Use when
- Use for account or workspace settings that have independent server-owned sections.
## Avoid when
- Use a small settings dialog when there are only one or two reversible controls.
## Rules
- Render the installed page with `<x-pages.settings-page />` and pass data through its props; edit the copied file only for structural changes.
- Keep the semantic design tokens (`bg-background`, `text-muted-foreground`); never swap in raw colour utilities.
- Keep the `data-slot` attributes and the logical (start/end) spacing so the markup still mirrors under `dir="rtl"`.
## Links
- Docs: https://brokui.dev/pages/settings-page
- Registry JSON (files, props, contract): https://brokui.dev/r/open/pages/settings-page.json
Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.
Guidance
Use when
- Use for account or workspace settings that have independent server-owned sections.
Avoid when
- Use a small settings dialog when there are only one or two reversible controls.
Anti-patterns
- Do not replace semantic props with conflicting utility classes.
- Do not remove labels, focus styles, or state attributes.
- Anatomy
- Theming hooks
Usage
Render the page as a component, or wire it to a route. Pass data where useful:
<x-pages.settings-page />
Built from blocks & primitives
This page composes installed <brok:*> primitives and semantic design
tokens only — it does not reimplement any primitive. Re-theme it (light, dark, admin, customer) by
editing CSS variables; flip the preview to RTL to confirm it mirrors.
Source
The exact, editable file ui:add writes
into your app. The preview above renders this same source — there are no preview-only pages.
{{--
Settings Page 01 — a full account-settings screen that composes the
settings-* blocks behind a sticky section nav. No JS: the nav is anchor
links to each section (scroll-mt keeps headings clear of the viewport top),
so it is robust and fully accessible. Swap or reorder the <section>s to fit
your app; each wraps a single installed settings block.
--}}
@props([
'profileHref' => '#',
'actions' => null,
'billingLinks' => null,
'statusMessage' => null,
])
@php
$actions ??= [
'profile' => '#',
'billing' => '#',
'security' => '#',
'notifications' => '#',
'integrations' => '#',
];
$billingLinks ??= ['upgrade' => '#', 'cancel' => '#', 'payment' => '#'];
@endphp
<main id="main-content" data-visual-contracts="VC-010">
<x-ui.form.guard
data-slot="page-settings"
class="mx-auto w-full max-w-5xl px-4 py-8 sm:px-6 lg:px-8"
>
<header class="mb-8 flex flex-wrap items-end justify-between gap-4">
<div>
<h1 class="text-2xl font-semibold tracking-tight text-foreground">{{ __('Settings') }}</h1>
<p class="mt-2 text-sm text-muted-foreground">{{ __('Manage your profile, billing, security, notifications and integrations.') }}</p>
</div>
<x-ui.button :href="$profileHref" variant="outline">{{ __('View profile') }}</x-ui.button>
</header>
@if ($statusMessage)
<x-ui.alert variant="success" role="status" class="mb-6">{{ __($statusMessage) }}</x-ui.alert>
@endif
<div class="grid gap-8 lg:grid-cols-[12rem_minmax(0,1fr)]">
<nav class="min-w-0 lg:sticky lg:top-8 lg:self-start" aria-label="{{ __('Settings sections') }}">
<ul class="flex w-full max-w-full gap-2 overflow-x-auto pb-2 lg:flex-col lg:gap-0.5 lg:overflow-visible lg:pb-0">
@foreach ([
'profile' => 'Profile',
'billing' => 'Billing',
'security' => 'Security',
'notifications' => 'Notifications',
'integrations' => 'Integrations',
] as $anchor => $label)
<li>
<a
href="#{{ $anchor }}"
class="block whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>{{ __($label) }}</a>
</li>
@endforeach
</ul>
</nav>
<div class="min-w-0 space-y-12">
<section id="profile" class="scroll-mt-8" aria-label="{{ __('Profile') }}">
<x-blocks.settings-account :action="$actions['profile'] ?? '#'" />
</section>
<section id="billing" class="scroll-mt-8" aria-label="{{ __('Billing') }}">
<x-blocks.settings-billing
:upgrade-href="$billingLinks['upgrade'] ?? '#'"
:cancel-href="$billingLinks['cancel'] ?? '#'"
:payment-href="$billingLinks['payment'] ?? '#'"
/>
</section>
<section id="security" class="scroll-mt-8" aria-label="{{ __('Security') }}">
<x-blocks.settings-security :action="$actions['security'] ?? '#'" />
</section>
<section id="notifications" class="scroll-mt-8" aria-label="{{ __('Notifications') }}">
<x-blocks.settings-notifications :action="$actions['notifications'] ?? '#'" />
</section>
<section id="integrations" class="scroll-mt-8" aria-label="{{ __('Integrations') }}">
<x-blocks.settings-integrations :action="$actions['integrations'] ?? '#'" />
</section>
</div>
</div>
</x-ui.form.guard>
</main>
Ownership & lifecycle
Owner, release state, review evidence and adoption for this item.
- Owner
- Platform UI (@JoshJML)
- Current version
-
1.3.4 - Status
- Stable
- License
-
open - Deprecation
- Not deprecated
- Contract
-
v2 - Foundation
-
≥ 1.0.0