Overview
First read through this guide to see if there's anything that you might need to adjust. While there are many items on this page, a majority of them only apply to addons or custom code. We've noted who each item would apply to so you can more easily scan through the changes.
Upgrade using Composer
In your composer.json
, change the statamic/cms
requirement:
"statamic/cms": "3.4.*" "statamic/cms": "^4.0"
Then run:
composer update statamic/cms --with-dependencies
High impact changes
PHP and Laravel support
Affects apps using PHP < 8 or Laravel < 9.
- The minimum version of PHP is now 8.0.
- The minimum version of Laravel is now 9.
AMP has been removed
Affects apps using the AMP feature.
AMP is considered a dead project, and no longer provides SEO benefits, so the entire AMP feature has been removed.
API filters are opt-in
Affects apps using the GraphQL or REST API features.
All filters are disabled by default now for increased security. You must opt into each one you want made available.
// config/statamic/api.php or config/statamic/graphql.php 'resources' => [ 'collections' => true, 'collections' => [ 'blog' => [ 'allowed_filters' => ['title', 'slug'] ] ] ]
If you try to use a filter that has not been explicitly allowed, it will result in a validation error.
Medium impact changes
Route namespaces have been removed
Affects apps or addons using PHP-based routes.
When using the following various methods of adding custom routes, previously Statamic would assume a namespace. In 4.0, the namespace is removed.
Standard Laravel routes that you've added to your app routes files are not affected.
-
Statamic::pushCpRoutes()
-
Statamic::pushWebRoutes()
-
Statamic::pushActionRoutes()
- Addon route files
- Addon service provider
$this->registerCpRoutes()
- Addon service provider
$this->registerWebRoutes()
- Addon service provider
$this->registerActionRoutes()
For example, in an addon's cp.php
routes file:
Route::get('example', 'ExampleController@foo');// v3 = Your\Addon\Http\Controllers\ExampleController@foo// v4 = ExampleController@foo
In an addon, if you want a namespace, you can add one with a property:
protected $routeNamespace = 'Your\Addon\Http\Controllers';
However, we recommend using the class reference syntax:
use Your\Addon\Http\Controllers\ExampleController; Route::get('example', [ExampleController::class, 'foo']);
Str::replace arguments changed
Affects apps or addons using Statamic\Support\Str::replace()
.
The Statamic\Support\Str::replace()
method changed the argument order. The $subject
argument moved from first to last.
Str::replace($subject, $search, $replace); Str::replace($search, $replace, $subject);
Tailwind 3
Affects apps or addons with custom CP components.
The Control Panel has been upgraded from Tailwind 1 to 3. The sizing scale has been adjusted. Custom components may render unexpectedly and may need to have classes renamed.
Entry date behavior
Affects apps or addons with custom code.
When using the date
method on an entry, an exception will be thrown if the entry is not in a dated collection.
Because of this, if you are creating an entry instance, you should set the collection before the date.
Entry::make() ->date($date) ->collection($collection) ->date($date) ->set('foo', 'bar');
Low impact changes
Control Panel Composer actions have been removed
Affects users who are used to updating Statamic and addons using the Control Panel.
The ability to update Statamic, as well as installing and updating addons through the Control Panel has been removed. You will now need to use Composer on the command line.
The Control Panel sections remain, however the buttons will now give you the Composer commands rather than running them for you.
jQuery removed
Affects apps or addons with custom CP components using jQuery.
jQuery and jQuery UI were seldom used, and have been removed to lower the CP's overhead. We suggest replacing with Vue or Alpine equivalents.
vue-reactive-provide removed
Affects custom CP Vue components using the reactiveProvide
property.
The vue-reactive-provide
package was removed. We suggest using providing an observed object.
reactiveProvide: { name: 'foo', include: ['alfa', 'bravo']} provide: { foo: this.foo},data() { foo: this.makeProvidedFoo();},methods: { makeProvidedFoo() { const foo = {}; Object.defineProperties(grid, { alfa: { get: () => this.alfa }, bravo: { get: () => this.bravo }, }); return foo; }}
Flysystem v1 support dropped
Affects apps or addons explicitly using Flysystem v1 code.
Support for league/flysystem
v1 has been removed. Only v3 is supported.
CommonMark v1 support dropped
Affects apps or addons with custom CommonMark v1 extensions.
Support for league/commonmark
v1 has been removed. Only v2 is supported.
Typography CSS styling
Affects apps or addons with custom CP components using the clean-content
CSS class.
The custom .clean-content
css class in the Control Panel has been replaced by .prose
from Tailwind's typography plugin.
FontAwesome and Entypo fonts have been removed
Affects apps or addons with custom CP components using these fonts.
Both icon fonts have been removed, and replaced with Streamline SVG icons.
SortableList delay has been reduced to zero
Affects apps or addons with custom CP components using the SortableList
component.
The delay was reduced from 200 to 0. The prop still exists, so you can manually bring it back.
<sortable-list> <sortable-list :delay="200">
However, we suggest using a distance over delay in most cases.
<sortable-list :distance="10">
Panes have been removed
Affects apps or addons with custom CP components using the Pane
component.
The "pane" feature has been removed. You can replace it with a narrow stack.
<pane> <stack narrow> Some content</pane> </stack>
Color fieldtype has been simplified
Affects apps using the color
fieldtype in their blueprints.
The color fieldtype now only supports hex values with no alpha channel.
PortalVue and vue-js-modal components have been renamed.
Affects apps or addons with custom CP components using the <portal>
or <vue-modal>
components.
Statamic v4 introduces our own <portal>
component, so to prevent conflicts, the underlying PortalVue package's component has been renamed to <v-portal>
.
<portal><v-portal> ...</portal></v-portal>
For consistency, we renamed the underlying modal component from <vue-modal>
to <v-modal>
.
<vue-modal><v-modal> ...</vue-modal></v-modal>