DEV Community

hadakadenkyu
hadakadenkyu

Posted on • Edited on

How to pass values from PHP to JavaScript using Laravel Vite

import.meta.url.

For JavaScript modules, you can use the import.meta object to access its own meta information.

import.meta - JavaScript | MDN

Therefore,

<script type="module" src="app.js?someURLInfo=5"></script>
Enter fullscreen mode Exit fullscreen mode

At this time, app.js module is able to get its own URL with query parameters and hash through import.meta.url.
In other words, You can pass values via query parameters like

new URL(import.meta.url).searchParams.get('someURLInfo') // '5';
Enter fullscreen mode Exit fullscreen mode

Using with Laravel Vite

Normally you would use @vite directive to load js file like

@vite('resources/js/app.js')
Enter fullscreen mode Exit fullscreen mode

so to pass a value through query parameter, you would write something like

@vite('resources/js/app.js?someURLInfo=5')
Enter fullscreen mode Exit fullscreen mode

but this doesn't work.
To be precise, it works for local development by starting the development server with npm run dev, but when you deploy to production by running npm run build, it will fail to reference the generated js file and give you a 500 error.

Fortunately, according to the Laravel documentation the Vite plugin has a method called createAssetPathsUsing that changes the path value as an advanced customization.

https://readouble.com/laravel/11.x/en/vite.html#advanced-customization

In short, you can write like this.

    {{
        Vite::withEntryPoints(['resources/js/app.js'])
            ->createAssetPathsUsing(function (string $path, ?bool $secure) {
                return "/{$path}?someURLInfo=5";
            })
    }}
Enter fullscreen mode Exit fullscreen mode

However, this now works fine in production, but when you start a development server with npm run dev and try to develop locally, it ignores what you set in createAssetPathsUsing and doesn't work.

Nonetheless, since one works well on the production server and the other works well on the development server, it seems like it would be a good idea to combine both. To do this, we need to determine if it is under development or not.

Luckily, the Vite class provides such a method.
The isRunningHot is it.

https://laravel.com/api/11.x/Illuminate/Support/Facades/Vite.html#method_isRunningHot

TL;DR

// Note that to create an alias for Vite
// 'Vite' => \Illuminate\Support\Facades\Vite::class,
@if(Vite::isRunningHot())
@vite('resources/js/app.js?someURLInfo=5')
@else
    {{
        Vite::withEntryPoints(['resources/js/app.js'])
            ->createAssetPathsUsing(function (string $path, ?bool $secure) {
                return "/{$path}?someURLInfo=5";
            })
    }}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)