Vite
is a modern frontend build tool that provides an extremely fast development environment and bundles your code for production. When building applications with Laravel, you will typically use Vite to bundle your application's CSS and JavaScript files into production ready assets.
Laravel integrates seamlessly with Vite by providing an official plugin and Blade directive to load your assets for development and production.
Are you running Laravel Mix? Vite has replaced Laravel Mix in new Laravel installations. For Mix documentation, please visit the
Laravel Mix
website. If you would like to switch to Vite, please see our
migration guide
.
Before transitioning to Vite, new Laravel applications utilized
Mix
, which is powered by
webpack
, when bundling assets. Vite focuses on providing a faster and more productive experience when building rich JavaScript applications. If you are developing a Single Page Application (SPA), including those developed with tools like
Inertia
, Vite will be the perfect fit.
Vite also works well with traditional server-side rendered applications with JavaScript "sprinkles", including those using
Livewire
. However, it lacks some features that Laravel Mix supports, such as the ability to copy arbitrary assets into the build that are not referenced directly in your JavaScript application.
Have you started a new Laravel application using our Vite scaffolding but need to move back to Laravel Mix and webpack? No problem. Please consult our
official guide on migrating from Vite to Mix
.
The following documentation discusses how to manually install and configure the Laravel Vite plugin. However, Laravel's
starter kits
already include all of this scaffolding and are the fastest way to get started with Laravel and Vite.
You must ensure that Node.js (16+) and NPM are installed before running Vite and the Laravel plugin:
node -v
npm -v
You can easily install the latest version of Node and NPM using simple graphical installers from
the official Node website
. Or, if you are using
Laravel Sail
, you may invoke Node and NPM through Sail:
Within a fresh installation of Laravel, you will find a
package.json
file in the root of your application's directory structure. The default
package.json
file already includes everything you need to get started using Vite and the Laravel plugin. You may install your application's frontend dependencies via NPM:
Vite is configured via a
vite.config.js
file in the root of your project. You are free to customize this file based on your needs, and you may also install any other plugins your application requires, such as
@vitejs/plugin-vue
or
@vitejs/plugin-react
.
The Laravel Vite plugin requires you to specify the entry points for your application. These may be JavaScript or CSS files, and include preprocessed languages such as TypeScript, JSX, TSX, and Sass.
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
});
If you are building an SPA, including applications built using Inertia, Vite works best without CSS entry points:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
],
});
Instead, you should import your CSS via JavaScript. Typically, this would be done in your application's
resources/js/app.js
file:
import'./bootstrap';
import'../css/app.css';
The Laravel plugin also supports multiple entry points and advanced configuration options such as
SSR entry points
.
If your local development web server is serving your application via HTTPS, you may run into issues connecting to the Vite development server.
If you are using
Laravel Herd
and have secured the site or you are using
Laravel Valet
and have run the
secure command
against your application, the Laravel Vite plugin will automatically detect and use the generated TLS certificate for you.
If you secured the site using a host that does not match the application's directory name, you may manually specify the host in your application's
vite.config.js
file:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel({
// ...
detectTls: 'my-app.test',
}),
],
});
When using another web server, you should generate a trusted certificate and manually configure Vite to use the generated certificates:
// ...
import fs from'fs';
consthost='my-app.test';
exportdefaultdefineConfig({
// ...
server: {
host,
hmr: { host },
https: {
key: fs.readFileSync(`/path/to/${host}.key`),
cert: fs.readFileSync(`/path/to/${host}.crt`),
},
},
});
If you are unable to generate a trusted certificate for your system, you may install and configure the
@vitejs/plugin-basic-ssl
plugin
. When using untrusted certificates, you will need to accept the certificate warning for Vite's development server in your browser by following the "Local" link in your console when running the
npm run dev
command.
When running the Vite development server within
Laravel Sail
on Windows Subsystem for Linux 2 (WSL2), you should add the following configuration to your
vite.config.js
file to ensure the browser can communicate with the development server:
// ...
exportdefaultdefineConfig({
// ...
server: {
hmr: {
host: 'localhost',
},
},
});
If your file changes are not being reflected in the browser while the development server is running, you may also need to configure Vite's
server.watch.usePolling
option
.
With your Vite entry points configured, you may now reference them in a
@vite()
Blade directive that you add to the
<head>
of your application's root template:
If you're importing your CSS via JavaScript, you only need to include the JavaScript entry point:
<!DOCTYPEhtml>
<head>
{{-- ... --}}
@vite('resources/js/app.js')
</head>
The
@vite
directive will automatically detect the Vite development server and inject the Vite client to enable Hot Module Replacement. In build mode, the directive will load your compiled and versioned assets, including any imported CSS.
If needed, you may also specify the build path of your compiled assets when invoking the
@vite
directive:
<!doctypehtml>
<head>
{{-- Given build path is relative to public path. --}}
Sometimes it may be necessary to include the raw content of assets rather than linking to the versioned URL of the asset. For example, you may need to include asset content directly into your page when passing HTML content to a PDF generator. You may output the content of Vite assets using the
content
method provided by the
Vite
facade:
There are two ways you can run Vite. You may run the development server via the
dev
command, which is useful while developing locally. The development server will automatically detect changes to your files and instantly reflect them in any open browser windows.
Or, running the
build
command will version and bundle your application's assets and get them ready for you to deploy to production:
By default, The Laravel plugin provides a common alias to help you hit the ground running and conveniently import your application's assets:
{
'@'=>'/resources/js'
}
You may overwrite the
'@'
alias by adding your own to the
vite.config.js
configuration file:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel(['resources/ts/app.tsx']),
],
resolve: {
alias: {
'@': '/resources/ts',
},
},
});
If you would like to build your frontend using the
Vue
framework, then you will also need to install the
@vitejs/plugin-vue
plugin:
npm install--save-dev@vitejs/plugin-vue
You may then include the plugin in your
vite.config.js
configuration file. There are a few additional options you will need when using the Vue plugin with Laravel:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
import vue from'@vitejs/plugin-vue';
exportdefaultdefineConfig({
plugins: [
laravel(['resources/js/app.js']),
vue({
template: {
transformAssetUrls: {
// The Vue plugin will re-write asset URLs, when referenced
// in Single File Components, to point to the Laravel web
// server. Setting this to `null` allows the Laravel plugin
// to instead re-write asset URLs to point to the Vite
// server instead.
base: null,
// The Vue plugin will parse absolute URLs and treat them
// as absolute paths to files on disk. Setting this to
// `false` will leave absolute URLs un-touched so they can
// reference assets in the public directory as expected.
includeAbsolute: false,
},
},
}),
],
});
Laravel's
starter kits
already include the proper Laravel, Vue, and Vite configuration. Check out
Laravel Breeze
for the fastest way to get started with Laravel, Vue, and Vite.
If you would like to build your frontend using the
React
framework, then you will also need to install the
@vitejs/plugin-react
plugin:
npm install--save-dev@vitejs/plugin-react
You may then include the plugin in your
vite.config.js
configuration file:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
import react from'@vitejs/plugin-react';
exportdefaultdefineConfig({
plugins: [
laravel(['resources/js/app.jsx']),
react(),
],
});
You will need to ensure that any files containing JSX have a
.jsx
or
.tsx
extension, remembering to update your entry point, if required, as
shown above
.
You will also need to include the additional
@viteReactRefresh
Blade directive alongside your existing
@vite
directive.
@viteReactRefresh
@vite('resources/js/app.jsx')
The
@viteReactRefresh
directive must be called before the
@vite
directive.
Laravel's
starter kits
already include the proper Laravel, React, and Vite configuration. Check out
Laravel Breeze
for the fastest way to get started with Laravel, React, and Vite.
The Laravel Vite plugin provides a convenient
resolvePageComponent
function to help you resolve your Inertia page components. Below is an example of the helper in use with Vue 3; however, you may also utilize the function in other frameworks such as React:
If you are using Vite's code splitting feature with Inertia, we recommend configuring
asset prefetching
.
Laravel's
starter kits
already include the proper Laravel, Inertia, and Vite configuration. Check out
Laravel Breeze
for the fastest way to get started with Laravel, Inertia, and Vite.
When using Vite and referencing assets in your application's HTML, CSS, or JS, there are a couple of caveats to consider. First, if you reference assets with an absolute path, Vite will not include the asset in the build; therefore, you should ensure that the asset is available in your public directory. You should avoid using absolute paths when using a
dedicated CSS entrypoint
because, during development, browsers will try to load these paths from the Vite development server, where the CSS is hosted, rather than from your public directory.
When referencing relative asset paths, you should remember that the paths are relative to the file where they are referenced. Any assets referenced via a relative path will be re-written, versioned, and bundled by Vite.
Consider the following project structure:
public/
taylor.png
resources/
js/
Pages/
Welcome.vue
images/
abigail.png
The following example demonstrates how Vite will treat relative and absolute URLs:
<!-- This asset is not handled by Vite and will not be included in the build -->
<imgsrc="/taylor.png">
<!-- This asset will be re-written, versioned, and bundled by Vite -->
You can learn more about Vite's CSS support within the
Vite documentation
. If you are using PostCSS plugins such as
Tailwind
, you may create a
postcss.config.js
file in the root of your project and Vite will automatically apply it:
exportdefault {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Laravel's
starter kits
already include the proper Tailwind, PostCSS, and Vite configuration. Or, if you would like to use Tailwind and Laravel without using one of our starter kits, check out
Tailwind's installation guide for Laravel
.
When referencing assets in your JavaScript or CSS, Vite automatically processes and versions them. In addition, when building Blade based applications, Vite can also process and version static assets that you reference solely in Blade templates.
However, in order to accomplish this, you need to make Vite aware of your assets by importing the static assets into the application's entry point. For example, if you want to process and version all images stored in
resources/images
and all fonts stored in
resources/fonts
, you should add the following in your application's
resources/js/app.js
entry point:
import.meta.glob([
'../images/**',
'../fonts/**',
]);
These assets will now be processed by Vite when running
npm run build
. You can then reference these assets in Blade templates using the
Vite::asset
method, which will return the versioned URL for a given asset:
When your application is built using traditional server-side rendering with Blade, Vite can improve your development workflow by automatically refreshing the browser when you make changes to view files in your application. To get started, you can simply specify the
refresh
option as
true
.
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel({
// ...
refresh: true,
}),
],
});
When the
refresh
option is
true
, saving files in the following directories will trigger the browser to perform a full page refresh while you are running
npm run dev
:
Watching the
routes/**
directory is useful if you are utilizing
Ziggy
to generate route links within your application's frontend.
If these default paths do not suit your needs, you can specify your own list of paths to watch:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel({
// ...
refresh: ['resources/views/**'],
}),
],
});
Under the hood, the Laravel Vite plugin uses the
vite-plugin-full-reload
package, which offers some advanced configuration options to fine-tune this feature's behavior. If you need this level of customization, you may provide a
config
definition:
It is common in JavaScript applications to
create aliases
to regularly referenced directories. But, you may also create aliases to use in Blade by using the
macro
method on the
Illuminate\Support\Facades\Vite
class. Typically, "macros" should be defined within the
boot
method of a
service provider
:
Once a macro has been defined, it can be invoked within your templates. For example, we can use the
image
macro defined above to reference an asset located at
resources/images/logo.png
:
When building an SPA using Vite's code splitting feature, required assets are fetched on each page navigation. This behavior can lead to delayed UI rendering. If this is a problem for your frontend framework of choice, Laravel offers the ability to eagerly prefetch your application's JavaScript and CSS assets on initial page load.
You can instruct Laravel to eagerly prefetch your assets by invoking the
Vite::prefetch
method in the
boot
method of a
service provider
:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Vite;
use Illuminate\Support\ServiceProvider;
classAppServiceProviderextendsServiceProvider
{
/**
* Register any application services.
*/
publicfunctionregister():void
{
// ...
}
/**
* Bootstrap any application services.
*/
publicfunctionboot():void
{
Vite::prefetch(concurrency: 3);
}
}
In the example above, assets will be prefetched with a maximum of
3
concurrent downloads on each page load. You can modify the concurrency to suit your application's needs or specify no concurrency limit if the application should download all assets at once:
/**
* Bootstrap any application services.
*/
publicfunctionboot():void
{
Vite::prefetch();
}
By default, prefetching will begin when the
page
load
event
fires. If you would like to customize when prefetching begins, you may specify an event that Vite will listen for:
/**
* Bootstrap any application services.
*/
publicfunctionboot():void
{
Vite::prefetch(event: 'vite:prefetch');
}
Given the code above, prefetching will now begin when you manually dispatch the
vite:prefetch
event on the
window
object. For example, you could have prefetching begin three seconds after the page loads:
If your Vite compiled assets are deployed to a domain separate from your application, such as via a CDN, you must specify the
ASSET_URL
environment variable within your application's
.env
file:
ASSET_URL=https://cdn.example.com
After configuring the asset URL, all re-written URLs to your assets will be prefixed with the configured value:
Laravel's Vite integration will attempt to resolve your assets while running your tests, which requires you to either run the Vite development server or build your assets.
If you would prefer to mock Vite during testing, you may call the
withoutVite
method, which is available for any tests that extend Laravel's
TestCase
class:
test('without vite example',function(){
$this->withoutVite();
// ...
});
use Tests\TestCase;
classExampleTestextendsTestCase
{
publicfunctiontest_without_vite_example():void
{
$this->withoutVite();
// ...
}
}
If you would like to disable Vite for all tests, you may call the
withoutVite
method from the
setUp
method on your base
TestCase
class:
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCaseas BaseTestCase;
The Laravel Vite plugin makes it painless to set up server-side rendering with Vite. To get started, create an SSR entry point at
resources/js/ssr.js
and specify the entry point by passing a configuration option to the Laravel plugin:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
ssr: 'resources/js/ssr.js',
}),
],
});
To ensure you don't forget to rebuild the SSR entry point, we recommend augmenting the "build" script in your application's
package.json
to create your SSR build:
"scripts": {
"dev": "vite",
"build": "vite build"
"build":"vite build && vite build --ssr"
}
Then, to build and start the SSR server, you may run the following commands:
npm runbuild
node bootstrap/ssr/ssr.js
If you are using
SSR with Inertia
, you may instead use the
inertia:start-ssr
Artisan command to start the SSR server:
php artisaninertia:start-ssr
Laravel's
starter kits
already include the proper Laravel, Inertia SSR, and Vite configuration. Check out
Laravel Breeze
for the fastest way to get started with Laravel, Inertia SSR, and Vite.
After invoking the
useCspNonce
method, Laravel will automatically include the
nonce
attributes on all generated script and style tags.
If you need to specify the nonce elsewhere, including the
Ziggy
@route
directive
included with Laravel's
starter kits
, you may retrieve it using the
cspNonce
method:
@routes(nonce: Vite::cspNonce())
If you already have a nonce that you would like to instruct Laravel to use, you may pass the nonce to the
useCspNonce
method:
If your Vite manifest includes
integrity
hashes for your assets, Laravel will automatically add the
integrity
attribute on any script and style tags it generates in order to enforce
Subresource Integrity
. By default, Vite does not include the
integrity
hash in its manifest, but you may enable it by installing the
vite-plugin-manifest-sri
NPM plugin:
npm install--save-devvite-plugin-manifest-sri
You may then enable this plugin in your
vite.config.js
file:
If you need to include additional attributes on your script and style tags, such as the
data-turbo-track
attribute, you may specify them via the
useScriptTagAttributes
and
useStyleTagAttributes
methods. Typically, this methods should be invoked from a
service provider
:
use Illuminate\Support\Facades\Vite;
Vite::useScriptTagAttributes([
'data-turbo-track'=>'reload', // Specify a value for the attribute...
'async'=>true, // Specify an attribute without a value...
'integrity'=>false, // Exclude an attribute that would otherwise be included...
]);
Vite::useStyleTagAttributes([
'data-turbo-track'=>'reload',
]);
If you need to conditionally add attributes, you may pass a callback that will receive the asset source path, its URL, its manifest chunk, and the entire manifest:
Out of the box, Laravel's Vite plugin uses sensible conventions that should work for the majority of applications; however, sometimes you may need to customize Vite's behavior. To enable additional customization options, we offer the following methods and options which can be used in place of the
@vite
Blade directive:
<!doctypehtml>
<head>
{{-- ... --}}
{{
Vite::useHotFile(storage_path('vite.hot')) // Customize the "hot" file...
->useBuildDirectory('bundle') // Customize the build directory...
->useManifestFilename('assets.json') // Customize the manifest filename...
->withEntryPoints(['resources/js/app.js']) // Specify the entry points...
->createAssetPathsUsing(function(string$path, ?bool$secure) { // Customize the backend path generation for built assets...
return"https://cdn.example.com/{$path}";
})
}}
</head>
Within the
vite.config.js
file, you should then specify the same configuration:
import { defineConfig } from'vite';
import laravel from'laravel-vite-plugin';
exportdefaultdefineConfig({
plugins: [
laravel({
hotFile: 'storage/vite.hot', // Customize the "hot" file...
buildDirectory: 'bundle', // Customize the build directory...
input: ['resources/js/app.js'], // Specify the entry points...
}),
],
build: {
manifest: 'assets.json', // Customize the manifest filename...
Some plugins within the Vite ecosystem assume that URLs which begin with a forward-slash will always point to the Vite dev server. However, due to the nature of the Laravel integration, this is not the case.
For example, the
vite-imagetools
plugin outputs URLs like the following while Vite is serving your assets:
The
vite-imagetools
plugin is expecting that the output URL will be intercepted by Vite and the plugin may then handle all URLs that start with
/@imagetools
. If you are using plugins that are expecting this behaviour, you will need to manually correct the URLs. You can do this in your
vite.config.js
file by using the
transformOnServe
option.
In this particular example, we will prepend the dev server URL to all occurrences of
/@imagetools
within the generated code:
Laravel is a web application framework with expressive, elegant syntax. We believe development must
be an enjoyable and creative experience to be truly fulfilling. Laravel attempts to take the pain
out of development by easing common tasks used in most web projects.
Laravel is a Trademark of Laravel Holdings Inc.
Code highlighting provided by
Torchlight