the easiest way to override laravel nova vue files is to create a tool, and load a component with the same name as the component you want to override.
In my case, i was creating a custom Nova action, laravel Nova doesn't support custom actions but you can do it anyway. In order for the custom Action to work, i need to override 2 laravel nova vue files. let me walk you through how i did it.
i started by creating a custom tool with the command php artisan nova:resource-tool vendor/package-name
. change the vendor and package name to your preference. The above command will create your tool folder and the nova-components
folder in the root of your Laravel Project.
Under the src
folder of your tool, you have the service provider class and the main tool class, my tool service provider looks like this
<?php
namespace TestTool\DataExportAction;
use Laravel\Nova\Nova;
use Laravel\Nova\Events\ServingNova;
use Illuminate\Support\ServiceProvider;
class ActionServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Nova::serving(function (ServingNova $event) {
Nova::script('data-export-action', __DIR__.'/../dist/js/action.js');
});
}
}
as you can see am only serving a js file.
My main tool class named DataExportAction.php
looks like this
<?php
namespace TestTool\DataExportAction;
use Laravel\Nova\Actions\Action;
abstract class DataExportAction extends Action
{
/**
* The filter's component.
*
* @var string
*/
public $component = 'data-export-action';
}
as you can see, extending the laravel Nova action base class located at nova/src/Actions/Action.php
and am overriding the vue component name here public $component = 'data-export-action';
In the tool resources/js
folder, i have the main tool.js
file which i renamed to action.js
and a components folder where we will place the vue components that will override the main Nova vue files.
in the action.js
file i have this
Nova.booting(Vue => {
Vue.component('data-export-action', require('./components/ConfirmActionModal'));
})
note the component name is the same as the one defined in DataExportAction
class
now in order to use the custom class, i create the default nova action class and instead of extending the nova/src/Actions/Action.php
class, i extend the DataExportAction
class and it will automatically use my custom component when loading the action.
now, in order to get more control over the action, i also need to override a Vue component located at nova/resources/js/components/ActionSelector.vue
. if you check the main nova components file located at nova/resources/js/components.js
, the component is loaded like this
...
import ActionSelector from '@/components/ActionSelector'
Vue.component('action-selector', ActionSelector)
...
create an ActionSelector.vue
file in the tool components folder with the contents of nova/resources/js/components/ActionSelector.vue
.
then in action.js
file, add the line
Vue.component('action-selector', require('./components/ActionSelector'));
now the action.js
file will look like
Nova.booting(Vue => {
Vue.component('data-export-action', require('./components/ConfirmActionModal'));
Vue.component('action-selector', require('./components/ActionSelector'));
})
note that we don't change the component name, now when Nova loads the action-selector
component, it will load our custom component instead of the default one
if you try to run npm to compile the js of the tool we just created you will get an error because the component we are overriding requires files that are only in the Nova node_modules folder, to solve this, we edit our webpack.mix.js
that looks like this
let mix = require('laravel-mix')
mix.setPublicPath('dist')
.js('resources/js/action.js', 'js');
to this
let mix = require('laravel-mix')
mix.setPublicPath('dist')
.js('resources/js/action.js', 'js')
.webpackConfig({
resolve: {
alias: {
'@/storage': path.resolve(__dirname, '../../nova/resources/js/storage'),
'@': path.resolve(__dirname, '../../nova/resources/js/'),
},
modules: [
path.resolve(__dirname, '../../nova/node_modules/'),
],
symlinks: false
},
});
so instead of using our tools node_modules
folder, we use the one in nova/
webpack should now compile successfully.
We have successfully overridden a Laravel Nova vue file
If you have questions, comment below, Cheers!!