Spectrum is now read-only. Learn more about the decision in our official announcement.


Rapidly create a custom admin console that content publishers will love. Twill is an open source CMS toolkit for Laravel, crafted by AREA 17.


Announcing Twill 2.0!

March 10, 2020 at 6:55am

Announcing Twill 2.0!

March 10, 2020 at 6:55am (Edited 2 years ago)
We're very excited to release Twill 2.0 after a few months of focus to really set the project up for success. We've responded to the community pain points, supporting both Laravel 6 and 7, removing the need to build blocks and assets, improving documentation, introducing automated testing, and many more updates and bug fixes you can read more about below.
We were also very positively surprised by the number and quality of external contributions. Twill now has 42 contributors, twice as much as our previous release, and community members are starting to provide excellent support to other developers from their experience working with it. Thanks a lot to everyone involved! Twill also surpassed 20k installs recently!
We also want to note we understood the concerns shared by the community about our lack of releases in the past few months, and hope that this release will make you love working with Twill even more after patiently waiting for it. Our support for Laravel 6 took time to perfect, with dependencies going deprecated. Our changes to the frontend build or to the repositories traits needed to be challenged in different codebases. Stability is key for our users and it was important for us to take the time to make it right.
We could have tagged Laravel 6 support earlier though, that's entirely true, and that's something we want to address moving forward. We will now commit to releasing at least once every month. We might not want to be as quick as Laravel with a major release every 6 months, but we will be more actively releasing even if it is for a few minor fixes, that's for sure. With that said, we also want to say thank you to all the developers that tested our changes on the master branch during the past few months. It's been incredibly helpful to get feedback and contributions from the community.
Check out our full changelog for more detailed instructions on how to update and everything new in 2.0.


Semantic versioning

When releasing Laravel 6 at Laracon US last year, Taylor Otwell explained why v6 instead of v5.9, since it wasn't a "paradigm changing" release for the framework. That was because Laravel adopted semantic versioning (major.minor.patch). For simplicity, and because this is common practice for open source projects, we made that shift as well.
Starting with Twill 2.0.0, major releases are released only when breaking changes are necessary, while minor and patch releases may be released as often as every week. Minor and patch releases should never contain breaking changes.
When referencing Twill from your composer.json file, you should always use a version constraint such as ^2.0, since major releases of Twill do include breaking changes.
Until recently, Laravel and Twill were following romantic versioning (paradigm.major.minor). This is why Twill 1.2.2 was not just about patches but new features and improvements as well. Because today's release includes breaking changes and Twill now follows semantic versionning, we have to tag it as 2.0.0, even if it is not a paradigm shift at all.

Laravel versions support

Twill 2.0 supports Laravel 6 and 7, but does not support Laravel 5.4 and 5.5 anymore. 5.6, 5.7 and 5.8 are still supported.
We've removed all references to deprecated Laravel helpers from Twill, updated dependencies, and deleted some deprecated code from dropping support of 5.4 and 5.5.
We've also migrated from the deprecated dimsav/laravel-translatable to astronomic/laravel-translatable.
We've removed the Debug Bar and Inspector debugging packages as Laravel now ships with Ignition and we felt like developers should be able to pick the tools they prefer.

Blocks and frontend build workflow

It is not necessary to rebuild Twill's frontend when working with blocks anymore. Their templates are now dynamically rendered in Blade and loaded at runtime by Vue. Practically, it means you do not need to run php artisan twill:blocks and npm run twill-build after creating or updating a block. Just reload the page to see your changes after saving your Blade file!
This is possible because Twill's blocks Vue components are simple single file components that only have a template and a mixin registration. Blocks components are now dynamically registered by Vue using x-template scripts that are inlined by Blade.
In the process, we've also migrated from Laravel Mix to the latest version of Vue CLI, to have better control over our build. That also allowed us to fix an issue that had been annoying to quite a few users: conflicts with your own application's Laravel Mix configuration. Now, Twill publishes it's manifest to its own directory with a custom name, and won't be a blocker to running both of your builds if necessary anymore.

Database migrations loading strategy

As recommended by Laravel's documentation, we've decided to load Twill's database migrations without publishing them. This will allow more flexibility in the future and it avoids polluting the host application migrations folder.
A boolean config key has been introduced to control this new behavior: twill.load_default_migrations. It defaults to true starting with Twill 2.0.
Even if you are migrating from a Twill 1.x application, you should not have to worry about running those new migrations as they have been modified to always check for existence (or inexistence) of tables and columns before doing anything. If you want to maintain migrations yourself, feel free to disable this option and use Twill's migrations folder as a source of truth to update yours.
We've also prepared for all tables to be prefixed by twill_ in the next major release and exposed new config keys to control their names so you can already start using prefixed tables with Twill 2.0.

Database migrations changes

Like Laravel, Twill now uses big integers in migrations helpers. This is a breaking change with backwards compatibility provided through the twill.migrations_use_big_integers configuration key.

Translation models

Twill now automatically takes care of your translations models fillable by reusing your translatedAttributes array as long as you define a $baseModuleModel, which now happens automatically when generating modules from the CLI. This is not a breaking change but we think you should update to this new approach to avoid duplicating your columns list in 2 files.


Smarter CLI

Twill's module command now offers available options through a series of questions and then generates model and migration files content dynamically depending on provided options, removing previous versions comments, providing a greatly improved developer experience.

Automated testing

TravisCI is now testing Twill on all currently supported and future PHP versions. Almost 60% of all the PHP code is now covered by a PHPUnit test! Syntax errors are being checked by PHP-CS-Fixer and Scrutinizer CI is now analyzing Twill's codebase at every single commit. Prettier is now configured to maintain Twill's PSR-2 style. PHPStan also helped us fixing a few issues.

CMS UI i18n

The CMS UI can now be translated. We are shipping this update with Russian and Chinese translations. CMS users can choose their preferred language in their profile. As we are updating this changelog, French, German, Dutch, Portuguese and Polish translations have already been contributed by the community.


enter image description here
In order to provide HTML tables support in the WYSIWYG form field, we've integrated the Tiptap editor with Twill. You can use it by using the new type option of the wysiwyg form field, with the tiptap value. You can then enable the table button in your toolbarOptions.

OAuth login

You can enable the new twill.enabled.users-oauth feature to let your users login to the CMS using any third party service supported by Laravel Socialite.

JSON fields groups

It is now possible to automatically save and retrieve multiple form fields in a single JSON column in database. See #410.

Azure uploads

A new endpoint_type to support Azure storage of all uploads, exactly like when working with S3.

Free layout

We added a new layout to enable creating custom pages, keeping the navigation of your admin console. See our dedicated documentation section.

Automated browsers and repeaters

Clean up your repositories with this new feature that will automatically save and retrieve browser and repeaters fields for you. See #400.

Destroy records in the trash

It is finally possible to destroy and bulk destroy records in the trash!

Duplicate records

Records can now be duplicated from the listing page.

Subdomain routing

Enabling the new 'twill.support_subdomain_admin_routing' config key allows adding top level keys to Twill's navigation and dashboard modules configuration, mapping to a subdomain. This is a very simple way to implement multi-tenant CMS/sites in Twill.

And more...

  • Add form utils component aliases 5d5fa662
  • Add sideFieldset and sideFieldsets sections to form 807674a2
  • Add slot to publisher component f4fceac4
  • Fix #90 Add maxlength option to image metadata 54233d21
  • Allow enabling svg rendering parameters in Imgix and Glide services e3d89bc0
  • Add disabled property in the form submitOptions 9129e642
  • Support custom repository in dashboard and buckets configuration 9d3578e3
  • Expose glide configuration b95ca7f6
  • Added get preset url for glide 26015870
  • Support multi-browsers in blocks f6cea4e5
  • Add FilterLinks on Listings and Buckets3a83a069/c4c22bee
  • Add new icons c762ea21
  • #397 Support Glide Presets 6afbbf5b
  • #521 Added support for nested repeaters in block 0470afda
  • #526 Implement updateRepeater() for morphMany relations 26a0d2de
  • #528 Added an extra prop to repeater field to override the name 0ce0c4cc
  • #551 Display and apply default filters in listings 77eb7f23
  • #562 Add new fieldNote option to browser, medias and files fields aa7a1c5d


  • #371 Fix maps implementation when printing values from an array. e6a6ac2d
  • #380 Bug fix with undefined route name when blocks-editor is disabled eaacdbcc
  • #381 Add check on translatable input store to prevent duplicate field objects 2544d059
  • #385 Fix create superadmin user Artisan command 2425ea37
  • #390 Fix ignoring current email in UserRequest 9a6a1c10
  • #395 Fixed TTY issue for twill build command #236 90141c36
  • #402 When hydrating an old revision, include the ID so relationship methods don't fail 62914c81
  • #418 Fix join() syntax 57fbdaf1
  • #421 Display error when the blocks dir is not found fed7b92f
  • #423 Fix missing /js/blocks dir on twill:blocks command 47440423
  • #425 Fix published being sent as string on json 1cafa780
  • #427 Fix google2fa settings not being enabled 702e31a3
  • #429 Fix some deprecated helpers 2f1e3489
  • #431 fixed an http & https issue from APP URL abb1509f
  • #446 Fixed 'delete' => true not working in indexOptions, refs #289 81a32414
  • #449 Fix « Handle Repeater » feature compatibility with Laravel 5.6 7b0a275f
  • #459 Wysiwyg - Counter limit (fix counter limit in Textfield) 01151e54
  • #460 Wysiwyg - Make sure quill is ready when checking content length 392f29c0
  • #461 Forms with no Content fieldset : fix sticky publisher module and fix sticky nav sections 9a87a2b7
  • #469 Check the index exists before trying to save browsers in blocks d1c99948
  • #475 Fix the admin url of an element in the browser listing 44ad2182
  • #481 Fix typo in docs for nested module 764d9fc2
  • #484 Fix join() syntax in MediaLibrary/Glide.php 40288a9f
  • #485 Fix/destroy sub module ce5d88a0
  • #506 add required namespaces for Arr and Str in views and blade macros ff811087
  • #509 Fix inconsistent use of integer and bigInteger on MariaDB 10.3 c36252de
  • #523 Fixed a bug causing select field not accepting default to be false d1ca7681
  • #536 Exception handler should return json response on ajax call dec4714a
  • #539 Fix getSlug() function when locale fallback is activated c48ca396
  • Fix #41 – Use text columns for medias and files uuid, alt_text, caption and filename, make alt_text nullable 96cdebd8
  • Fix #504 Swap order of breadcrumbs and secondary nav 2f9a9070
  • Apply mine filters on dashboard drafts only if revisions are enabled 0481894d
  • Fix activity log breaking on destroyed subjects d1a18490
  • Fix lang switcher border 4ca820fa
  • Fix spacing issues dfea4805
  • Fix isAjax check on VSelect component 46a6b424
  • Force assets publish on twill:update 21e3fda9
  • Fix deeper Twill namespaces d64a1585
  • Fix typo for issue #362 ac76481c
  • Fix environment requirements in docs 40ab9d93
  • Fix #290 implementation 076ed178
  • Fix missing AWS_ROOT variable 2a467f22
  • Fix #399 dashboard repositories service container resolution 8491bbf5
  • Fix regression on form notifications 991a6212
  • Fix bulk delete warning modal reference b515028e
  • Fix module maker migration generator 8e7fd67f
  • Fix migration stub typo ea14f330
  • Form - Make sure $disableContentFieldset is defined 296cb90d
  • Prevent LQIP generator command crashes by letting it skip on exceptions 68d9ad6c


  • #386 Refactor calling trait methods from repository 7e45019e
  • #387 Refactor getLanguageLabelFromLocaleCode to use php intl's "Locale::getDisplayLanguage" e85ff145
  • #396 Added Logo and Badges to README 3bb38272
  • #398 Responsive filters b95820f4
  • #404 Change the way of maintaining Twill version number d4ba16a3
  • #430 Move logic to model e1ac4abf
  • #442 Implement a Sortable function closer to the one offered by Translatable. e46b2318
  • #445 Replace bcrypt() with Hash::make in CreateSuperAdmin command 00711ede
  • #450 Add style for subscript into wysiwyg 8e00ed1e
  • #500 Extend slug character support fe888ffe
  • #534 Slug characters extended 42071f08
  • #537 Refactored HandleRepeaters trait 136e7123
  • #538 Refactored HandleBrowsers trait 61a1e810
  • 2.0 version and docs updates f7f2aff1
  • Allow using the content editor even if revisions are disabled b0095e4f
  • Add message clarifying grouped validation error messages in blocks e35afce6
  • More 2.0 docs adjustements e39e029f
  • 2.0 documentation updates 09e22483
  • Allow firstOrCreate to have only attributes 01415792
  • Use bold font in wysiwyg editor content bbb1bb99
  • Disable Quill warnings 4fc8f3a7
  • Consider itemLabel better in browser and files form fields 57e4d9da
  • Button : add download and rel attributes cc790342
  • Button with a:href : update props and add target 9a2cdd8c
  • CSS - set default button as inline block to avoid small visual regression 416dcb4c
  • Button update default styling so it works with ahref 204efc6b
  • Refactor Button component so it is using render function and can be used to display links 993b8bee
  • Invert sorting order in ModuleRepository. 78a36d7f

We hope you enjoy this release, we're already excited about the next one!

March 10, 2020 at 7:41am
Great. How easy it is to migrate from 1.2 to 2.0. Is there any migration guide? Will it break anything?
Congratulations to all of the team that worked so hard for this big achievement!!!
Thanks so much and the team! Looking forward to trying to upgrade a few existing projects ;)
While it's really been a long time, I think it was worth waiting. I've already migrated my WIP projects and started using the new features, there are some great ones. I think Twill is getting to a point where it can be used as a full-featured production CMS replacing dinosaurs like WP and Joomla. Thank you for making this happen!
one thing to do that would really help Twill self promote is to update the demo site you have and make it include new Twill 2.0 features. If there is any chance of making a new site that uses lots of the functionality and then also copying that site into a github repro that would be an amazing reference.
Happy days. Awesome!
Congrats! Félicitations! Can't wait to give it a go!
Thanks to everybody at AREA17 for your hard work on the project and this version. Twill 2.0 looks like a really polished release. Excited to be using it for existing and new projects going forward 🌀

March 13, 2020 at 6:25pm

March 30, 2020 at 5:22pm
any plans for a 2.0.2 soon with some of the recent bug fixes applied?

March 31, 2020 at 6:02pm
uh, nice to see see tiptap here 😍