Files
Obsidian-Vault/Work/Projects/Laravel-v12-Migration/Logs/upgrade-log-hgbi.md
2026-02-24 08:10:57 +01:00

18 KiB

Update Log: HGBI — Laravel 11 → 12 + Ecosystem

Date: 2026-02-20 Branch: updates-to-v12 AI Tool: Claude Code (Opus 4.6)


Starting State

Package Before Target
PHP 8.4.17 (no change expected)
laravel/framework 11.48.0 ^12.0
filament/filament 3.3.49 ^5.0
livewire/livewire 3.7.10 ^4.0 (via Filament)
tailwindcss 3.4.19 ^4.0
pestphp/pest 4.x (no change expected)

Baseline tests: 249 passed (1774 assertions), 3 risky, 20 incomplete Baseline build: Success (client + SSR)


Upgrade Phases

Phase 1: Pre-Flight

  • Branch created (updates-to-v12)
  • Baseline tests recorded
  • Baseline build verified
  • Reference document consulted

Phase 2: Composer — Remove Blockers

  • codezero/laravel-localizer removed
  • codezero/laravel-localized-routes replaced with opgginc/codezero-laravel-localized-routes:^5.0
  • codezero/composer-preload-files set to false in allow-plugins
  • saloonphp/laravel-http-sender removed, config/saloon.php updated to GuzzleSender
  • johncarter/filament-focal-point-picker removed and usage cleaned from 2 files
  • Bootstrap cache cleared
  • Tests pass (249), build succeeds

Phase 3: Composer — Laravel 12 + Direct Dependencies

  • Laravel framework 12.52.0 installed
  • All direct dependencies bumped (see Packages Changed table)
  • spatie/icalendar-generator v3 enum syntax fixed (EventStatus::Confirmed, Classification::Private)
  • Bootstrap cache cleared
  • Tests pass (249), build succeeds

Phase 4: Filament v3 → v5

  • filament/spatie-laravel-translatable-plugin removed (no v4/v5 exists)
  • Filament v5.2.2 installed directly (v4 intermediary had no translatable support)
  • filament/upgrade:^4.0 installed, filament-v4 rector run on app/
  • filament/upgrade:^5.0 installed, filament-v5 rector run on app/
  • lara-zeus/spatie-translatable:^2.0 installed (replaces translatable plugin)
  • DisplayText::make() signature fixed (?string $name = null)
  • TextInput\Mask replaced in ShippingRateResource and CouponResource
  • FaqsRelationManager form signature fixed (Schema $schema)
  • Livewire v4.1.4 installed (via Filament)
  • Tests pass (249), build succeeds

Phase 5: NPM Major Updates

  • Major frontend packages upgraded
  • vite.config.js SSR fix: @inertiajs/server@inertiajs/vue3
  • @vue/server-renderer deduplicated (removed from dependencies, kept in devDependencies)
  • apexcharts added as explicit dependency (previously transitive)
  • Build succeeds (client + SSR)
  • Tests pass (249)

Phase 6: ESLint Cleanup

  • eslint-plugin-tailwindcss removed from devDeps and eslint.config.mjs
  • Tailwind-specific rules/settings cleaned from ESLint config
  • Linter passes

Phase 7: Final Verification (Laravel 12 Upgrade)

  • Tests pass: 249 passed (1774 assertions), 3 risky, 20 incomplete — matches baseline
  • Build succeeds (client + SSR)
  • Pint passes (--dirty --format agentpass)
  • composer outdated --direct → all up to date
  • npm outdated → only deferred packages (eslint 10, tailwindcss 4, globals 17)
  • php artisan about → Laravel 12.52.0

Phase 8: Tailwind CSS v3 → v4

  • Automated upgrade tool (@tailwindcss/upgrade) run — partially succeeded
    • Migrated app.css directives (@import 'tailwindcss', @config reference, border compat layer)
    • Updated tailwindcss package to ^4.2.0
    • Failed on: callback-based theme extensions (negative), then tailwindcss/defaultTheme module removed in v4
  • Manual fixes applied:
    • Callback theme extensions (inset: (theme, {negative}) => ...) converted to static ...generateSpacing() objects
    • tailwindcss/defaultTheme import removed, font stack inlined
    • @tailwindcss/postcss installed, postcss.config.js updated (removed autoprefixer)
    • @layer base@utility blocks in utility.css (13 utilities converted)
    • Custom-class-in-custom-class patterns expanded (inner-container/container/outer-container no longer @apply pl-container pr-container)
    • Container override: @source not inline('container') added to app.css (ref #37)
    • corePlugins.container = false removed from JS config (not supported in v4 CSS-first mode)
    • Old TW v3 plugins removed: @tailwindcss/forms, @tailwindcss/typography, @tailwindcss/aspect-ratio, autoprefixer
    • require() plugin calls removed from tailwind.config.js (forms/typography now built into v4)
    • @formkit/themes/tailwindcss plugin kept — works in compat mode
  • Deprecated TW v3 class patterns updated in 4 Vue files:
    • bg-gray-500 bg-opacity-75bg-gray-500/75 (3 modal components)
    • ring-black ring-opacity-5ring-black/5 (1 component)
  • Build succeeds (client + SSR)
  • Tests pass: 249 passed (1774 assertions) — matches baseline
  • Filament assets republished (php artisan filament:upgrade --no-interaction)

Phase 9: Final Verification

  • Tests pass: 249 passed (1774 assertions), 3 risky, 20 incomplete — matches baseline
  • Build succeeds (client + SSR)
  • npm outdated → only deferred packages (eslint 10, globals 17)

Exceptions & Issues

Issue 1: Saloon HttpSender config broke after removing laravel-http-sender

Symptom: 17 test failures in Labonovum/Saloon-related tests after removing saloonphp/laravel-http-sender. Root Cause: config/saloon.php referenced Saloon\HttpSender\HttpSender which was in the removed package. Then changed to Saloon\Laravel\HttpSender which also doesn't exist in v3. Fix: Changed to Saloon\Http\Senders\GuzzleSender (the default in saloonphp/laravel-plugin v3). Files affected: config/saloon.php

Issue 2: spatie/icalendar-generator v3 enum method syntax changed

Symptom: Call to undefined method Spatie\IcalendarGenerator\Enums\EventStatus::confirmed() Root Cause: v3 switched from method-based enums to PHP 8.1 backed enums (::Confirmed instead of ::confirmed()). Fix: EventStatus::confirmed()EventStatus::Confirmed, Classification::private()Classification::Private Files affected: provider/Models/Appointment.php

Issue 3: filament/spatie-laravel-translatable-plugin has no v4 or v5

Symptom: No v4/v5 release exists. Plugin only has v3.x which requires filament/support:self.version (v3), blocking Filament upgrade. Root Cause: The translatable plugin was deprecated by Filament and replaced by a community package. Fix: Removed filament/spatie-laravel-translatable-plugin, installed lara-zeus/spatie-translatable:^2.0. Rector scripts automatically migrated all 40+ imports. Files affected: All Filament resource files using translatable traits.

Issue 4: ariaieboy/filament-currency v3 requires Filament v5

Symptom: ariaieboy/filament-currency:^3 requires filament/tables ^5.0, blocking Filament v4 installation. Root Cause: v3.0.0 skipped v4 support entirely. Fix: Went directly to Filament v5, installed ariaieboy/filament-currency:^3.

Issue 5: DisplayText::make() signature incompatibility

Symptom: Declaration of App\Forms\Components\DisplayText::make(string $name = ''): static must be compatible with Filament\Forms\Components\Field::make(?string $name = null): static Root Cause: Filament v4+ changed Field::make() from string $name to ?string $name = null (ref #17). Fix: Updated to make(?string $name = null) and pass $name ?? '' to parent. Files affected: app/Forms/Components/DisplayText.php

Issue 6: TextInput\Mask removed in Filament v5

Symptom: use Filament\Forms\Components\TextInput\Mask import fails. Root Cause: Mask builder class removed in Filament v5 (ref #15). Fix: Replaced mask closures with ->numeric()->step(0.01)->minValue(0)->prefix('€') approach. Files affected: app/Filament/Resources/ShippingRateResource.php, app/Filament/Resources/CouponResource.php

Issue 7: Missing apexcharts npm dependency

Symptom: Rollup failed to resolve import "apexcharts" during build. Root Cause: vue3-apexcharts requires apexcharts as peer dep, previously resolved transitively (ref #51). Fix: Added apexcharts as explicit dependency. Files affected: package.json

Issue 8: Tailwind upgrade tool fails on callback-based theme extensions

Symptom: Cannot destructure property 'negative' of 'undefined' Root Cause: tailwind.config.js used callback functions for theme extensions (e.g., inset: (theme, {negative}) => ...). TW v4's upgrade tool cannot evaluate these. Fix: Converted all callback-based theme extensions to static objects using ...generateSpacing(). Files affected: tailwind.config.js

Issue 9: tailwindcss/defaultTheme module removed in TW v4

Symptom: Cannot find module 'tailwindcss/defaultTheme' during upgrade tool template migration step. Root Cause: TW v4 removed the defaultTheme export. The config imported it for fontFamily.sans fallback stack. Fix: Removed the import, inlined the default sans font stack directly. Files affected: tailwind.config.js

Issue 10: Custom .container class overridden by TW v4 built-in

Symptom: Potential layout breakage — TW v4 generates its own .container utility that would override the project's custom one. Root Cause: corePlugins.container = false from JS config is not supported in TW v4 CSS-first mode (ref #37). Fix: Added @source not inline('container') and @source not inline('container!') to app.css. Files affected: resources/css/app.css

Issue 11: @layer base with @apply fails in TW v4

Symptom: Cannot apply unknown utility class when building. Root Cause: TW v4 no longer supports @apply inside @layer base for custom utility classes (ref #35). Fix: Converted all @layer base custom utilities to @utility blocks. Non-@apply styles (.hide-scrollbar, .lds-ellipsis, etc.) moved to plain CSS. Files affected: resources/css/utility.css


Packages Changed

Package From To Notes
laravel/framework 11.48.0 12.52.0 Core upgrade
filament/filament 3.3.49 5.2.2 Skipped v4 (no translatable)
livewire/livewire 3.7.10 4.1.4 Via Filament
barryvdh/laravel-debugbar 3.16.5 4.0.9 Clean
darkaonline/l5-swagger 9.0.1 10.1.0 Clean
mollie/laravel-mollie 3.1.0 4.0.2 Clean
predis/predis 2.4.1 3.4.0 Clean
spatie/eloquent-sortable 4.5.2 5.0.0 Clean
spatie/calendar-links 1.11.1 2.0 Not used in code
spatie/icalendar-generator 2.9.2 3.2.1 Enum syntax change
laravel-notification-channels/fcm 4.5.0 6.0.1 Skipped v5
muhammadhuzaifa/telescope-guzzle-watcher 3.2.2 4.0.0 Clean
staudenmeir/belongs-to-through 2.16.4 2.17 Clean
staudenmeir/eloquent-has-many-deep 1.20.x 1.21 Clean
amidesfahani/filament-tinyeditor 3.x 4.x Clean
ariaieboy/filament-currency 1.x 3.0.0 Clean
ralphjsmit/laravel-filament-components 2.x 3.x Clean
filament/spatie-laravel-media-library-plugin 3.3.49 5.2.2 Clean
filament/spatie-laravel-settings-plugin 3.3.49 5.2.2 Clean
codezero/laravel-localized-routes 4.0.1 Removed
codezero/laravel-localizer 3.0.0 Removed
saloonphp/laravel-http-sender 3.1.0 Removed (abandoned)
johncarter/filament-focal-point-picker 3.1.0 Removed
filament/spatie-laravel-translatable-plugin 3.3.49 Removed
opgginc/codezero-laravel-localized-routes 5.1.0 Added (fork)
lara-zeus/spatie-translatable 2.0.0 Added (replaces translatable plugin)
laravel-vite-plugin 1.3.0 2.1.0 Requires Vite 7
vite 6.4.1 7.3.1 Required by laravel-vite-plugin
@vitejs/plugin-vue 5.2.4 6.0.4 Required by Vite 7
@vueuse/core 13.9.0 14.2.1 Clean
@vueuse/integrations 13.9.0 14.2.1 Clean
vue-i18n 9.14.5 11.2.8 Clean
uuid 11.1.0 13.0.0 Clean
vue-number-animation 1.1.2 2.0.2 Needs --legacy-peer-deps
imagetools-core 7.1.0 9.1.0 Clean
vite-imagetools 7.1.1 9.0.3 Clean
rollup-plugin-visualizer 5.14.0 6.0.5 Clean
eslint-plugin-tailwindcss 3.18.0 Removed
apexcharts 5.6.0 Added (was transitive)
tailwindcss 3.4.19 4.2.0 CSS-first mode with @config compat
@tailwindcss/postcss 0.1.3 Added (replaces tailwindcss plugin)
@tailwindcss/forms 0.5.4 Removed (built into v4)
@tailwindcss/typography 0.5.9 Removed (built into v4)
@tailwindcss/aspect-ratio 0.4.2 Removed (built into v4)
autoprefixer 10.4.14 Removed (built into v4)

What Worked Without Issues

  • darkaonline/l5-swagger 9 → 10: no code changes
  • mollie/laravel-mollie 3 → 4: no code changes
  • spatie/eloquent-sortable 4 → 5: no code changes
  • predis/predis 2 → 3: no code changes
  • barryvdh/laravel-debugbar 3 → 4: only bootstrap cache clear needed
  • staudenmeir/belongs-to-through and eloquent-has-many-deep: patch bumps, clean
  • All Filament companion plugins (media-library, settings, tinyeditor, currency, components): clean upgrades
  • @vueuse/core and @vueuse/integrations 13 → 14: no breaking changes encountered
  • vue-i18n 9 → 11: no import changes needed
  • uuid 11 → 13: no changes needed
  • Filament rector scripts (v4 + v5): handled most namespace transforms correctly
  • lara-zeus/spatie-translatable:^2.0: drop-in replacement, rector migrated all imports
  • @formkit/themes/tailwindcss plugin: works in TW v4 compat mode via @config without changes

Remaining / Unresolved

  • ESLint v9 → v10: Intentionally deferred (+ globals 16 → 17).
  • vue-number-animation peer dep conflict: Installed with --legacy-peer-deps. The v2 package has an optional peer dep on @vue/composition-api which conflicts with Vue 3. Works correctly at runtime.
  • npm audit vulnerabilities: 15 high, 1 moderate — review separately.
  • Tailwind v4 visual validation: Build succeeds but manual visual validation is required. TW v4 changes CSS output in subtle ways that automated tests cannot detect. Open key pages in browser and compare against pre-upgrade state.
  • tailwind.config.js still uses JS compat mode: The project uses @config in CSS to load the JS config. A future cleanup could migrate everything to pure CSS-first @theme {} blocks, but this is not required and the compat mode works correctly.

Miscellaneous

  • Tailwind CSS v3 → v4 completed in Phase 8. Uses @config compat mode (JS config still present).
  • ESLint v9 → v10 is not in scope.
  • Filament v4 step was effectively skipped due to translatable plugin incompatibility. Went v3 → v5 directly, but ran both v4 and v5 rector scripts.
  • The post-update-cmd script in composer.json runs filament:upgrade automatically on every composer update/require, which generates large diffs in public/js/filament/* and public/css/filament/*.
  • spatie/calendar-links upgraded to v2 but is not referenced anywhere in code (might be removable).

Recommendations for Next Session

  • Manual visual validation of key pages (homepage, product pages, Filament admin, provider dashboard, modals). TW v4 changes CSS output subtly — a green build does not guarantee correct layout.
  • Consider removing spatie/calendar-links if truly unused.
  • Review and address npm audit vulnerabilities.
  • Consider migrating tailwind.config.js to pure CSS-first @theme {} blocks (optional, compat mode works fine).
  • ESLint v10 upgrade when ready.