Начало работы: Laravel + Inertia
React-стартер Laravel (Inertia 3): ThemeProvider — в withApp, атрибуты темы — в Blade-шаблоне, фон и шрифт стартера уступают теме
1. Создайте приложение
Проверено с Laravel 13.36 и Inertia 3.9. Без --stability=dev Composer берёт устаревший тег стартера (Laravel 12, Inertia 2). Скрипты Composer сами создают .env, ключ, SQLite-базу и собирают фронтенд.
composer create-project laravel/react-starter-kit my-app --stability=dev --no-interaction
cd my-app
2. Установите пакет
Подходят react и react-dom 17, 18 и 19 (на React 17 id из useId появляются сразу после монтирования). Пакет — ES-модули (плюс CommonJS-копия для require()), без runtime-зависимостей, по файлу на модуль: в бандл попадают только импортированные компоненты, а как грузить и CSS только их — в разделе «Только нужный CSS» ниже. Шрифты — отдельные файлы: тема vercel (по умолчанию в ThemeProvider) использует Geist, поэтому рядом со стилями импортируйте valyro-ui/fonts/geist.css и valyro-ui/fonts/geist-mono.css, иначе текст будет системным шрифтом; glass использует системные шрифты, ей файлы не нужны. Пока пакет не опубликован, соберите и упакуйте его в репозитории (npm run build:core && npm pack ./dist/core) и установите tarball из корня репозитория: npm install /path/to/ValyroUI/valyro-ui-0.1.0.tgz.
npm install valyro-ui
3. Стили и ThemeProvider
В Inertia 3 нет setup() с <App /> — корневая обёртка задаётся колбэком withApp. При SSR задайте locale в ThemeProvider: иначе числа и даты форматируются по локали сервера, а в браузере — по локали пользователя, и гидрация падает на несовпадении текста («1,200» против «1 200»).
import { createInertiaApp } from '@inertiajs/react';
import 'valyro-ui/styles.css';
import { ThemeProvider } from 'valyro-ui';
import { Toaster } from '@/components/ui/sonner';
import { TooltipProvider } from '@/components/ui/tooltip';
import { initializeTheme } from '@/hooks/use-appearance';
import AppLayout from '@/layouts/app-layout';
import AuthLayout from '@/layouts/auth-layout';
import SettingsLayout from '@/layouts/settings/layout';
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
void createInertiaApp({
title: (title) => (title ? `${title} - ${appName}` : appName),
layout: (name) => {
switch (true) {
case name === 'welcome':
return null;
case name.startsWith('auth/'):
return AuthLayout;
case name.startsWith('settings/'):
return [AppLayout, SettingsLayout];
default:
return AppLayout;
}
},
strictMode: true,
withApp(app) {
return (
<ThemeProvider theme="glass" mode="light" locale="en-US">
<TooltipProvider delayDuration={0}>
{app}
<Toaster />
</TooltipProvider>
</ThemeProvider>
);
},
progress: {
color: '#4B5563',
},
});
// This will set light / dark mode on load...
initializeTheme();
4. Тема в Blade-шаблоне
Добавьте атрибуты на <html> и уберите font-sans с <body>: шрифт стартера через font: inherit из preflight Tailwind перебивает шрифт темы даже в кнопках. Уберите и @fonts из <head>: он предзагружает Instrument Sans стартера, который больше не используется (три лишние загрузки и предупреждения «preloaded but not used» в консоли). Собственная светлая/тёмная тема стартера (класс dark) с data-mode не синхронизирована — переключайте их вместе сами.
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" data-theme="glass" data-mode="light" @class(['dark' => ($appearance ?? 'system') == 'dark'])>
…
<body class="antialiased">
5. Уберите фон body
Правило стартера делает body непрозрачным и закрывает фон темы, который рисуется на <html>. Удалите его из @layer base.
/* …the rest of the file stays as is… */
@layer base {
* {
@apply border-border;
}
}
6. Страница
Showcase — компонент из гайда по Next.js, без изменений (в resources/js/components/showcase.tsx).
import { Head } from '@inertiajs/react';
import { Showcase } from '@/components/showcase';
export default function Welcome() {
return (
<>
<Head title="Welcome" />
<Showcase />
</>
);
}
7. Соберите и запустите
Без SSR Inertia рендерит страницу в браузере. С SSR (npm run build:ssr и php artisan inertia:start-ssr) серверный HTML уже содержит разметку компонентов, гидрация проходит без предупреждений.
npm run build
php artisan serve