You can specify any number of sources for the laravel-vite-plugin:
vite.config.js
export default defineConfig({
plugins: [
laravel([
'resources/css/welcome.css',
'resources/js/welcome.js',
'resources/css/app.css',
'resources/js/app.js',
'resources/css/admin.css',
'resources/js/admin.js',
]),
],
});
Finally, you use in each view only the ones you actually need.
resources/views/welcome.blade.php
<!DOCTYPE html>
<head>
{{-- ... --}}
@vite(['resources/css/welcome.css', 'resources/js/welcome.js'])
</head>
resources/views/app.blade.php
<!DOCTYPE html>
<head>
{{-- ... --}}
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
resources/views/admin.blade.php
<!DOCTYPE html>
<head>
{{-- ... --}}
@vite(['resources/css/admin.css', 'resources/js/admin.js'])
</head>
As you mentioned in the question, it's possible that you already have a separate <head>. In this case, most modern browsers will handle a secondary correctly, but you can pass variables from outside to layout.blade.php and then use them in @vite. (Reference: How to pass variable to @extends blade and Can HTML contain two HEAD tags)
resources/views/layout.blade.php
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ $title ?? config('app.name') }}</title>
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
@if(isset($sources))
@vite($sources)
@else
@vite(['resources/js/app.css', 'resources/js/app.js'])
@endif
</head>
resources/views/admin.blade.php
@extends('layout', ['sources' => ['resources/js/admin.css', 'resources/css/admin.js']])
@section('content')
<h1>Hello World</h1>
@endsection
Of course, you can also assemble the array passed to the plugin automatically. If your structure is known, you can read the file system accordingly and automatically collect the file paths.
For example, if you assume that every file in the js and css folders should be a separate source, but I ignore the subfolders, I would do something like this (when building the source, for instance, files used from the js/utils subfolder are bundled into the source by Vite, so you don't need to worry about that):
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import fs from 'fs';
import path from 'path';
function getFilesFromDir(dir) {
return fs.readdirSync(dir)
.filter(file => {
const ext = path.extname(file);
return (!ignoreFiles.includes(file) && (exts.length === 0 || exts.includes(ext)));
})
.map(file => path.join(dir, file).replace(/\\/g, '/'));
}
const cssFiles = getFilesFromDir('resources/css', ['.css']);
const jsFiles = getFilesFromDir('resources/js', ['.js']);
export default defineConfig({
plugins: [
laravel([
...cssFiles,
...jsFiles,
]),
],
});
Note: It's just a quick illustrative example; there might be a better alternative.
laravel()plugin insidevite.config.js. On the client side, you load only those you want to use on a given view, but you can choose from the values passed to thelaravel()plugin.glob? Or it's different? Because right now how I use it withglobit also automatically populate it (However not thevite.config.jsfile, but maybe it's similar?) Do you maybe have a link that shows how I can do what you said?