Getting Started
This guide builds a single page from PHP and registers a route for it. It assumes you have completed Installation.
Define a page
Section titled “Define a page”A page extends Lattice\Lattice\Http\Page. It returns a title() and builds its UI in render() by populating the PageSchema with components.
<?php
namespace App\Pages;
use Lattice\Lattice\Attributes\AsPage;use Lattice\Lattice\Ui\Components\Card;use Lattice\Lattice\Ui\Components\Grid;use Lattice\Lattice\Ui\Components\Heading;use Lattice\Lattice\Ui\Components\Stack;use Lattice\Lattice\Ui\Components\Text;use Lattice\Lattice\Ui\Enums\Gap;use Lattice\Lattice\Ui\Enums\PageLayout;use Lattice\Lattice\Core\PageSchema;use Lattice\Lattice\Http\Page as BasePage;
#[AsPage(route: '/dashboard', layout: PageLayout::None, middleware: ['web'])]final class DashboardPage extends BasePage{ public function title(): string { return 'Dashboard'; }
public function render(PageSchema $schema): PageSchema { return $schema->schema([ Stack::make('dashboard') ->gap(Gap::Large) ->schema([ Heading::make('Dashboard'), Text::make('Everything below is described in PHP and rendered as React.'), Grid::make('stats') ->columns(2) ->schema([ Card::make('Orders', '128 this week.'), Card::make('Revenue', '$4,210 this week.'), ]), ]), ]); }}Route the page
Section titled “Route the page”There is no route file entry to write. Lattice scans the paths in lattice.discover (app/ by default), finds every class carrying a #[AsPage] attribute, and registers a route for it automatically. The route name auto-derives from the URI (/dashboard → dashboard); supply name: in the attribute to override it.
Visit /dashboard and the page renders through Inertia — no route file entry, no controller, and no Inertia page component to write by hand.
Sharing layout and middleware across pages
Section titled “Sharing layout and middleware across pages”Rather than repeating layout: and middleware: on every page, declare a shared base page and inherit from it:
use Lattice\Lattice\Attributes\AsPage;use Lattice\Lattice\Ui\Enums\PageLayout;use Lattice\Lattice\Http\Page as BasePage;
#[AsPage(layout: PageLayout::App, middleware: ['web'])]abstract class AppPage extends BasePage {}
#[AsPage(route: '/dashboard')] // inherits layout + web middlewarefinal class DashboardPage extends AppPage { /* title(), render() */ }Pages need the web middleware group for sessions, CSRF, and route-model binding. Setting it once on the shared base keeps individual pages clean.
To register pages explicitly — for example from a package — call Lattice::pages([DashboardPage::class]) in a service provider instead of relying on discovery.
Navigation
Section titled “Navigation”Navigation (sidebar and menus) is built from Menu and Sidebar layout components in PHP. See Navigation for details.
Where to go next
Section titled “Where to go next”- Forms and Tables for data entry and listings.
- Configuration to register definitions and tune discovery.
- Extending Lattice to add custom fields, components, and columns.