Views path
Update resource_path()
.
<?phpreturn [ 'paths' => [- resource_path('views'),+ resource_path(), ],];
Livewire
<?phpreturn [ - 'view_path' => resource_path('views/livewire'), + 'view_path' => resource_path('livewire'),];
Laravel Vite config
Add new View
namespace.
class AppServiceProvider extends ServiceProvider{ public function boot() { // ...+ View::addNamespace('new-app', resource_path('new-app')); }}
Blade templates
Update main template
<!DOCTYPE html><html><head> @isset($vite) {{ $vite }} @else @vite('views', 'app.ts', 3100) @endisset</head>
Create multiple layouts
php artisan make:component Layout/Viewsphp artisan make:component Layout/NewApp
<x-app> <x-slot name="vite"> @vite('views', 'app.ts', 3100) </x-slot> {{ $slot }}</x-app>
<x-app> <x-slot name="vite"> @vite('new-app', 'app.ts', 3200) </x-slot> {{ $slot }}</x-app>
Import layout in each app
With views
app.
<x-layouts.views> <div>Welcome</div></x-layouts.views>
With new-app
app.
mkdir resources/new-appmkdir resources/new-app/pagestouch resources/new-app/pages/index.blade.php
<x-layouts.new-app> <div>Welcome</div></x-layouts.new-app>
Routes
Create route to serve page.
<?phpnamespace App\Http\Controllers;class MainController extends Controller{ public function index() { return view('views.pages.index'); } public function newApp() { return view('new-app.pages.index'); }}
<?phpuse Illuminate\Support\Facades\Route;Route::get('/', [MainController::class, 'index'])->name('welcome');Route::get('/new-app', [MainController::class, 'newApp'])->name('new-app');
Vite configurations
Into each app
Create two Vite configuration for each application: resources/views/vite.config.ts
and resources/new-app/vite.config.ts
.
APPNAME
import path from 'path'import { defineConfig } from 'vite'import { baseConfig, bladePlugin } from '../../vite.config'// https://vitejs.dev/config/export default defineConfig({ ...baseConfig(path.basename(__dirname)), resolve: { alias: { '~/APPNAME': `${__dirname}`, }, }, plugins: [bladePlugin()],})
Global configuration at root
import type { PluginOption, UserConfigExport } from 'vite'import Dotenv from 'dotenv'Dotenv.config()// https://vitejs.dev/config/export const baseConfig = (entry: string): UserConfigExport => { return { server: { hmr: { host: process.env.VITE_DEV_SERVER_HOST, }, }, base: '', root: `resources/${entry}`, publicDir: `${entry}/static`, build: { outDir: `../../public/assets/dist/${entry}`, emptyOutDir: true, manifest: true, rollupOptions: { input: '/app.ts', }, }, cacheDir: `../../node_modules/.vite/${entry}`, }}/** * Enable full reload for blade file */export const bladePlugin = (): PluginOption => ({ name: 'vite:laravel', handleHotUpdate({ file, server }) { if (file.endsWith('.blade.php')) { server.ws.send({ type: 'full-reload', path: '*', }) } },})
tsconfig.json
paths
Add new paths to tsconfig.json
{ "compilerOptions": { "paths": { "~/views": ["resources/views"], "~/views/*": ["resources/views/*"], "~/new-app": ["resources/new-app"], "~/new-app/*": ["resources/new-app/*"] } }}
Update package.json
scripts
pnpm add npm-run-all -D
{ "scripts": { "dev": "run-p dev:*", "build": "run-p build:*", "dev:views": "vite --config resources/views/vite.config.ts --port 3100 --host", "build:views": "vite build --config resources/views/vite.config.ts", "dev:newapp": "vite --config resources/new-app/vite.config.ts --port 3200 --host", "build:newapp": "vite build --config resources/new-app/vite.config.ts" }}
TypeScript
If you use TypeScript with Alpine JS or not, you have to move ts
files.
mv resources/app.ts resources/views/app.tsmv resources/global.d.ts resources/views/global.d.tsmv resources/ts resources/views/tsmv resources/app.css resources/views/app.css
touch resources/new-app/app.tstouch resources/new-app/global.d.tsmkdir resources/new-app/ts
import './app.css'// you can import Alpine JS here.