Installation
Installation Vite
Node.js packages
sh
pnpm i
sh
pnpm remove axios lodash
sh
pnpm add typescript -D
Views
php
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*/
public function boot()
{
View::addNamespace('front', resource_path('front'));
}
}
sh
mkdir resources/front
mkdir resources/front/components
mkdir resources/front/layouts
mkdir resources/front/pages
touch resources/front/global.d.ts
mv resources/css resources/front/css
mv resources/js resources/ts
mv resources/ts resources/front/ts
mv resources/front/ts/app.js resources/front/ts/app.ts
rm resources/front/ts/bootstrap.js
tsconfig.json
sh
touch tsconfig.json
json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"skipLibCheck": true,
"noImplicitAny": false,
"lib": ["esnext", "dom"],
"types": ["vite/client"],
"typeRoots": ["./node_modules/@types", "resources/**/*.d.ts"],
"paths": {
"~": ["./resources"],
"~/*": ["./resources/*"]
}
},
"include": [
"resources/**/*.ts",
"resources/**/*.d.ts",
"resources/**/*.tsx",
"resources/**/*.vue"
],
"exclude": [
"resources/views/stubs",
"resources/webreader/scripts/library",
"resources/admin/auto-imports.d.ts"
]
}
Vite
sh
mv vite.config.js vite.config.ts
ts
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
export default defineConfig({
plugins: [
laravel({
input: ["resources/front/css/app.css", "resources/front/ts/app.ts"],
refresh: ["resources/**"],
}),
],
});
Blade
sh
mkdir resources/views/components
touch resources/views/components/app.blade.php
html
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="csrf-token" content="{{ csrf_token() }}" />
<title>@yield('title', app_name())</title>
{{-- {!! SEO::generate() !!} --}}
<link rel="icon" type="image/x+ico" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
{{--
<script src="{{ asset('/color-mode.js') }}"></script>
--}} @stack('head') @stack('styles') {{-- @livewireStyles --}}
</head>
<body
class="{{ config('app.env') === 'local' ? 'debug-screens' : '' }} color-mode"
>
{{ $slot }} @stack('modals') @stack('scripts') {{-- @livewireScripts --}}
</body>
</html>
Layout
sh
touch resources/front/layouts/app.blade.php
html
<x-app>
@push('head') @vite(['resources/front/css/app.css',
'resources/front/ts/app.ts']) @endpush @yield('default')
</x-app>
Page
sh
touch resources/front/pages/index.blade.php
html
@extends('front::layouts.app') @section('default') Content @endsection
Controller
sh
php artisan make:controller Front/FrontController
php
<?php
namespace App\Http\Controllers\Front;
use App\Http\Controllers\Controller;
class FrontController extends Controller
{
public function index()
{
return view('front::pages.index');
}
}
Routes
php
Route::get('/', [FrontController::class, 'index'])->name('front.index');
spatie/laravel-route-attributes
sh
composer require spatie/laravel-route-attributes
sh
php artisan vendor:publish --provider="Spatie\RouteAttributes\RouteAttributesServiceProvider" --tag="config"
php
<?php
return [
// ...
'directories' => [
// app_path('Http/Controllers'),
],
// ...
];
php
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
use Spatie\RouteAttributes\RouteRegistrar;
class RouteServiceProvider extends ServiceProvider
{
public const HOME = '/home';
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'))
;
Route::middleware('web')
->group(base_path('routes/web.php'))
;
});
Route::name('front.')
->group(
fn () => (new RouteRegistrar(app(Router::class)))
->useRootNamespace(app()->getNamespace())
->useMiddleware(['web'])
->registerDirectory(app_path('Http/Controllers/Front'))
)
;
// Route::prefix('api')
// ->name('api.')
// ->group(
// fn () => (new RouteRegistrar(app(Router::class)))
// ->useRootNamespace(app()->getNamespace())
// ->useMiddleware(['api'])
// ->registerDirectory(app_path('Http/Controllers/Api'))
// )
// ;
}
// ...
}
php
<?php
namespace App\Http\Controllers\Front;
use App\Http\Controllers\Controller;
use Spatie\RouteAttributes\Attributes\Get;
class FrontController extends Controller
{
#[Get('/', name: 'front.index')]
public function index()
{
return view('front::pages.index');
}
}
diff
<?php
- Route::get('/', [FrontController::class, 'index'])->name('front.index');