Nova's upstream dependencies have been upgraded. You will find a complete list of our dependency upgrades below:
doctrine/dbal
from ^2.9
to ^2.13.3|^3.1.2|^4.0
laravel/ui
from ^2.0|^3.0
to ^3.3|^4.0
symfony/*
from ^5.0
to ^5.4|^6.0|^7.0
cakephp/chronos
and moontoast/math
dependenciesv1
to v6
flatpickr
and moment.js
You should update your laravel/nova
dependency to ^4.0
in your application's composer.json
file:
"laravel/nova": "^4.0",
After purchasing a Nova 4.0 license, you should update your Composer auth.json file to use your newly generated license key instead of your previous Nova 3 API token or account password.
Next, install your updated your Composer dependencies:
composer update mirrors
composer update
After updating your application's Composer dependencies, you should migrate your database:
php artisan migrate
Next, you should update your application's Nova configuration, assets, and translation files. To get started, you may run the following commands to update your assets and translations.
You may wish to store a copy of your current translation file before running this command so you can easily port any custom translations back into the new file after running these commands. In addition, we will generate a "Main" dashboard for your Nova installation:
php artisan nova:dashboard Main
php -r "file_exists('./resources/views/vendor/nova/layout.blade.php') && unlink('./resources/views/vendor/nova/layout.blade.php');"
php artisan vendor:publish --tag=nova-assets --force
php artisan vendor:publish --tag=nova-lang --force
php artisan view:clear
Next, let's update the Nova configuration file. First, ensure that the middleware
and api_middleware
configuration options within your application's nova
configuration file appear as follows:
use Laravel\Nova\Http\Middleware\Authenticate;
use Laravel\Nova\Http\Middleware\Authorize;
use Laravel\Nova\Http\Middleware\BootTools;
use Laravel\Nova\Http\Middleware\DispatchServingNovaEvent;
use Laravel\Nova\Http\Middleware\HandleInertiaRequests;
return [
// ...
'middleware' => [
'web',
HandleInertiaRequests::class,
DispatchServingNovaEvent::class,
BootTools::class,
],
'api_middleware' => [
'nova',
Authenticate::class,
Authorize::class,
],
// ...
];
Next, ensure your application's nova
configuration file contains a storage_disk
configuration option:
'storage_disk' => env('NOVA_STORAGE_DISK', 'public'),
Once your configuration has been updated, you should review the following list of changes and upgrade your application accordingly.
Nova requires a license key a production URL to be used in production environments. Nova will check your license key and the current host against the values from the license details found in your Nova account. You can learn more in the installation docs.
If your application relies on Nova tools or packages developed by third-parties, it is possible that these packages are not yet compatible with Nova 4.0 and will require an update from their maintainers.
Nova 4 updates a variety of methods to accept a Laravel\Nova\Http\Requests\NovaRequest
instance instead of an Illuminate\Http\Request
instance. An overview of the methods that have been updated is provided below so you may update your method signatures accordingly.
The fields
, fieldsForIndex
, fieldsForDetail
, fieldsForCreate
, fieldsForUpdate
, cards
, filters
, lenses
, and actions
methods:
class Resource
{
public function fields(NovaRequest $request) {}
public function fieldsForIndex(NovaRequest $request) {}
public function fieldsForDetail(NovaRequest $request) {}
public function fieldsForCreate(NovaRequest $request) {}
public function fieldsForUpdate(NovaRequest $request) {}
public function cards(NovaRequest $request) {}
public function filters(NovaRequest $request) {}
public function lenses(NovaRequest $request) {}
public function actions(NovaRequest $request) {}
}
The fields
, filters
, and actions
methods:
class Lens
{
public function fields(NovaRequest $request) {}
public function cards(NovaRequest $request) {}
public function filters(NovaRequest $request) {}
public function actions(NovaRequest $request) {}
}
The fields
method:
class Action
{
public function fields(NovaRequest $request) {}
}
The apply
and options
methods:
class Filter
{
public function apply(NovaRequest $request, $query, $value) {}
public function options(NovaRequest $request) {}
}
In previous releases of Nova, the "Main" dashboard cards were defined via the cards
method of your application's NovaServiceProvider
. However, in Nova 4, a dedicated Main
dashboard class must be created via the following command:
php artisan nova:dashboard Main
Next, move the contents of the cards
method from your NovaServiceProvider
to the cards
method of your new App\Nova\Dashboards\Main
class and register the Main
dashboard within the dashboards
method of your NovaServiceProvider
:
use App\Nova\Dashboards\Main;
/**
* Get the extra dashboards that should be displayed on the Nova dashboard.
*
* @return array
*/
protected function dashboards()
{
return [
new Main,
];
}
In Nova 4, the label
and uriKey
methods defined on dashboard classes are no longer static. You should update your methods accordingly:
/**
* Get the displayable name of the dashboard.
*
* @return string
*/
public function label()
{
return 'Post Stats';
}
/**
* Get the URI key for the dashboard.
*
* @return string
*/
public function uriKey()
{
return 'posts-dashboard';
}
Nova 4 removes the ability to rely on the client machine's timezone in order to display timezone related information. Instead, Nova 4 utilizes the application's "server side" timezone as defined by the timezone option in your application's app
configuration file.
Please refer to our documentation regarding timezone customization for more information.
Date
/ DateTime
Fields & HTML5 Nova 4 utilizes native <input type="date" />
and <input type="datetime-local" />
elements to render the Date
and DateTime
fields. Therefore, the following methods have been removed from Nova 4:
firstDayOfWeek()
format()
pickerFormat()
pickerDisplayFormat()
incrementPickerHourBy()
incrementPickerMinuteBy()
Unfortunately, Algolia is retiring their "Places" API on May 31, 2022; therefore, the Place
field has been deprecated and we encourage you to migrate to Text
fields for street addresses and cities.
Prerequisites
To ease upgrading custom packages to Nova 4, please review and copy the following files from Laravel Nova's src/Console/tool-stubs
directory to your own custom package:
nova.mix.js
package.json
webpack.mix.js
Since Nova 4 upgrades our frontend dependencies to Inertia, Vue 3, and Tailwind 2, it is necessary to review all custom tools and upgrade them accordingly. A general overview of the necessary changes can be found below; however, your custom Nova packages may require additional changes if they are depending on third-party packages that only support Vue 2 or prior versions of Tailwind.
This change primarily affects the installation of custom tools that utilize Vue routing.
Nova 4 has been updated to use Vue 3, in order to upgrade all custom cards, custom fields, custom filters, resource tools, and tools to support Vue 3, please make the following changes to your application's webpack.mix.js
:
// Before...
mix.js("resources/js/field.js", "js");
// After...
require("./nova.mix");
mix
.setPublicPath('dist')
.js('resources/js/tool.js', 'js')
.vue({ version: 3 })
.css('resources/css/tool.css', 'css')
.nova('vendor/package')
This change primarily affects the installation of custom tools that utilize Vue routing.
Nova 4 has replaced Vue router with Inertia.js. Therefore, custom tools should migrate from registering Vue routes to registering Inertia.js page components and backend routes. For example, given the following Nova 3 Vue router registration:
// Within tool.js...
Nova.booting((Vue, router) => {
router.addRoutes([
{
name: "sidebar-tool",
path: "/sidebar-tool",
component: require("./components/Tool"),
},
]);
});
When using Nova 4, you should register the tool component with Inertia like so:
// Within tool.js...
Nova.booting((Vue) => {
Nova.inertia("SidebarTool", require("./component/Tool").default);
});
Once your Vue component has been registered, you should define a server-side route definition for your tool so that it may be rendered:
// Within ToolServiceProvider.php...
use Illuminate\Http\Request;
use Laravel\Nova\Nova;
Nova::router()
->group(function ($router) {
$router->get('sidebar-tool', function (Request $request) {
return inertia('SidebarTool');
});
});
laravel-nova
NPM Dependency This change primarily affects the installation of custom tools that utilize Vue routing.
Prerequisite
To ease upgrading custom packages to support Nova 4, please review and copy the following files from Laravel Nova's src/Console/stubs
especially the following files:
nova.mix.js
packages.json
webpack.mix.js
Previous versions of Nova required the laravel-nova
NPM package. In 4.0, this is no longer the case as each mixin has been integrated into Nova itself. To upgrade any custom packages you've created, you must update your webpack.mix.js
file to define an alias to vendor/laravel/nova/resources/js/mixins/packages.js
:
Typically, custom Nova tools, resource tools, cards, and other custom packages that are being developed within a nova-components
directory of a Laravel application can reference Nova's own packages.js
file by defining a laravel-nova
alias that points to the file within the Nova installation that is located within your root application's vendor
directory. This alias is typically defined within the custom package's nova.mix.js
file:
'laravel-nova': path.join(
__dirname,
'../../vendor/laravel/nova/resources/js/mixins/packages.js'
),
Custom Nova packages that are developed outside of a nova-components
directory should declare laravel/nova
as a "dev" Composer dependency, and then define a laravel-nova
Mix alias that points to the packages.js
file within your custom package's vendor
directory:
'laravel-nova': path.join(
__dirname,
'vendor/laravel/nova/resources/js/mixins/packages.js'
),
In order to compile custom packages assets with laravel-nova
mixins you are required to prepare laravel/nova
's node_modules
by running the following command:
npm run nova:install
# Or use the explicit command...
npm --prefix='vendor/laravel/nova' ci
Nova 3 ignores event cancellation when creating or updating a resource. For example, the following code will still persist the User
resource to the database, even though the event listener returns false
:
User::updating(function ($model) {
return false;
});
However, this code will throw a Laravel\Nova\Exceptions\ResourceSaveCancelledException
exception in Nova 4.
Field::default
Method Only Applies to Create, Attach, & Action Requests Nova 4 will no longer resolve default values for "index" and "detail" requests. If you need to define a model's default attribute values, please utilize Eloquent's $attributes
property:
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The model's attributes.
*
* @var array
*/
protected $attributes = [
'timezone' => 'UTC',
];
}
Given the following field definition, Nova 3 will assume the relationship method is named purchased_books
; however, Nova 4 will correctly assume the relationship method is named purchasedBooks
.
BelongsToMany::make('Purchased Books'),
Action::actionClass
Method Removed Nova 4 no longer allows adding custom CSS styles to an action confirmation modal's buttons via the action's actionClass
method.
Nova 4 requires the authentication user provider to be eloquent
in order to resolve information regarding the currently authenticated user.
In your application's default config/auth.php
configuration file, the Eloquent user provider is specified and it is instructed to use the App\Models\User
model when retrieving users. You may change these values within your configuration file based on the needs of your application.
Nova 4 introduces a shorter key-value map in filter string URLs which reduces the overall length of the URL. This change doesn't affect bookmarked URLs; however, third party package tool developers who interact deeply with Vuex may wish to ensure their packages still work after this change.
Action::showOnTableRow
Method The Action::showOnTableRow
method has been deprecated. Instead, we suggest updating your code to use the showInline
method:
// Before...
(new ConsolidateTransaction)->showOnTableRow(),
// After...
(new ConsolidateTransaction)->showInline(),
(new ConsolidateTransaction)->onlyInline(),
(new ConsolidateTransaction)->exceptInline(),
Nova 4 introduce the following tweaks to authorization order / precedence:
view
a resource no longer depends on the viewAny
permission.view
and viewAny
permissions.canRun
method before falling back to the model's policy.Further detail regarding Nova authorization is available within the resource policy documentation and action authorization documentation.
Due to various changes in Nova 4.0, you should re-publish the Nova "stubs" if you have previously published them. You can accomplish this by executing the nova:stubs
Artisan command with the --force
option:
php artisan nova:stubs --force