Inertia/React + Wayfinder Frontend¶
The parts of Yaya Engine that are not the Filament admin panel
run on Inertia.js v2 with React: a Laravel controller renders Inertia::render('page-name'),
and the React component whose file matches that name (under
resources/js/pages/) is what the browser shows — there is no client-side
router and no separate SPA build, just one component per server route
[@pages-dir]. This pattern applies to both the small set of general pages
under resources/js/pages/ and to the whole
Yaya Manager console under
resources/js/pages/manager/. Outside manager/, the page set is
deliberately small: welcome.tsx (the public landing page), dashboard.tsx,
settings/profile.tsx, settings/appearance.tsx, and mcp/auth/login.tsx — a
separate login screen for MCP-token administration, distinct from both the
Filament login and the Manager login [@pages-dir].
From a Laravel route to a typed helper¶
The bridge between the two languages is Wayfinder, wired into the build as
@laravel/vite-plugin-wayfinder in vite.config.ts with
wayfinder({ formVariants: true }) [@vite-config]. The workflow runs in one
direction: a route is declared in PHP first — in routes/web.php,
routes/auth.php, routes/settings.php, routes/manager.php, or as a
Filament resource/page class — and Wayfinder generates a matching TypeScript
file under resources/js/routes/** or resources/js/actions/** the next time
Vite runs. These files are 100% generated and are never hand-edited; the
plugin regenerates them automatically on every dev server start and build.
The generated shape is consistent everywhere. Take the root route,
Route::get('/', fn () => Inertia::render('welcome'))->name('home') at
routes/web.php:22 [@web-routes]. Wayfinder emits a home export in
resources/js/routes/index.ts with a .url() method, verb-named callables
(.get(), .head()), a matching homeForm object for progressive-enhancement
<form> submission, and a @see routes/web.php:22 JSDoc comment repeated
above every generated member, linking each generated function straight back to
the PHP line that produced it [@routes-index]. welcome.tsx consumes this
directly — import { dashboard, login } from '@/routes' and
<Link href={dashboard()}> — so navigation targets are typed and refactor-safe:
renaming or moving a Laravel route regenerates the helper and produces a
TypeScript error at every call site that still points at the old shape,
instead of a silent broken link discovered at runtime [@welcome-page].
Wayfinder does not stop at plain routes. It walks the full App\...
namespace, so Filament resource and page classes get the same generated
helpers under resources/js/actions/App/Filament/Resources/** and
.../Pages/**, even though those classes are never rendered as Inertia pages
themselves [@actions-filament-dir]. This matters because it means any PHP
route or Filament action anywhere in the app is reachable from the frontend
through the same typed pattern — a future integration between the Manager
console and a Filament action would not need a hand-written fetch call, just
an import from the generated tree.
Styling and components¶
Tailwind is configured CSS-first, the Tailwind v4 pattern: there is no
tailwind.config.js in the repo, and the @tailwindcss/vite plugin reads
configuration straight out of resources/css/app.css, which uses
@import 'tailwindcss', @plugin 'tailwindcss-animate', @source directives
to point at Blade views, and an @theme block for design tokens like
--color-background [@app-css] [@vite-config]. components.json still
declares a tailwind.config path for tooling compatibility, but the file it
points to does not exist — shadcn's CLI and Tailwind v4 both tolerate this
because the real configuration lives in the CSS file [@components-json].
components.json configures shadcn/ui with style: "default",
baseColor: "neutral", cssVariables: true, and iconLibrary: "lucide"
[@components-json]. resources/js/components/ui/ holds the generated
primitives this produces — alert, avatar, badge, breadcrumb, button, card,
checkbox, collapsible, dialog, dropdown-menu, icon, input, label,
navigation-menu, select, separator, sheet, sidebar, skeleton, table, textarea,
toggle, toggle-group, and tooltip, each a thin Radix wrapper styled with
Tailwind [@ui-components-dir]. resources/js/lib/utils.ts exports the cn()
helper (clsx plus tailwind-merge) that every one of those components uses
to merge caller-supplied class names with its own defaults, plus a toUrl()
helper that normalizes Inertia's InertiaLinkProps['href'] — which can be
either a plain string or a Wayfinder route-definition object — down to a
string, so components that need a raw URL do not have to special-case which
form a href prop arrived in [@utils-ts].