Skip to content

Translation issue with Octane #6835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kichetof opened this issue Apr 25, 2025 · 6 comments
Closed

Translation issue with Octane #6835

kichetof opened this issue Apr 25, 2025 · 6 comments
Labels
bug Verified bug by the Nova team fix incoming A fix is in review

Comments

@kichetof
Copy link

kichetof commented Apr 25, 2025

  • Laravel Version: 12.10.2 /11/10 too
  • Nova Version: 5.5.4 / 4.x too
  • PHP Version: 8.4
  • Database Driver & Version: sqlite / mysql
  • Operating System and Version: Linux Docker
  • Browser type and version: Brave
  • Reproduction Repository: https://github.com/kichetof/nova-octane-docker

Description:

I've finally managed to reproduce my issue with Create :resource and Update :resource.

Image

My locale is set to French, it should display "Créer utilisateurs".

Issue happen when you call an endpoint outside of Nova with Octane enabled (FrankenPHP in my case).

video issue
video links https://github.com/kichetof/nova-octane-docker/blob/main/art/Nova-Octane-Issue.gif

Detailed steps to reproduce the issue on a fresh Nova installation:

First test:

Clone my repo, setup a user.
navigate to: http://localhost/health?fresh and you'll see some Nova translation in english (that's fine, we're outside of Nova registration)
navigate to: http://localhost/nova/resources/users and you'll see text in both language, french and english <-- issue ❌


Second test:

Take care of order
Reload worker: sail artisan octane:reload
navigate to: http://localhost/nova/resources/users and you'll see text in french as expected
navigate to: http://localhost/health?fresh and you'll see Nova translation in french


Third test: Disable Octane

Comment this line https://github.com/kichetof/nova-octane-docker/blob/c1b6bff767e8329b9a60ca3d6d7412ba51a56f10/docker-compose.yml#L20
Restart stack: sail down && sail up -d
navigate to: http://localhost/nova/resources/users and you'll see text in french as expected no matter which endpoint you visited before.
navigate to: http://localhost/health?fresh and you'll see Nova translation in english as expected

Investigation

Create :resource and Update :resource are used in \Laravel\Nova\Resource::createButtonLabel and \Laravel\Nova\Resource::updateButtonLabel.

Theses method are called in \Laravel\Nova\Nova::provideToScript via \Laravel\Nova\Nova::resourceInformation to setup Nova::$jsonVariables

Nova::$jsonVariables are transformed in Nova::jsonVariables who is called in \Laravel\Nova\Http\Middleware\HandleInertiaRequests::share and vendor/laravel/nova/resources/views/layout.blade.php

I suspect an issue with Request who isn't flushed between requests as it should be.
Octane flush shared properties in \Laravel\Octane\Listeners\PrepareInertiaForNextOperation
Nova flush $jsonVariables in \Laravel\Nova\Concerns\InteractsWithEvents::flushState

Thanks a lot for your help with this headache issue!!

@kichetof
Copy link
Author

Whether it's due to circumstances or not, when this translation display problem occurs, my events (though Observer) and searches via Scout no longer works while Octane is reloaded.

@crynobone
Copy link
Member

crynobone commented Apr 26, 2025

Image

  1. Nova::translations() is only loaded when the request serves Nova (endpoint going to Nova routes) as it is registered under Nova::serving() event and this is only send to the frontend for translation in Vue.
  2. Laravel's translation only attempts to load JSON translation once https://github.com/laravel/framework/blob/fef0498be5f61ce5fae45a8a8a0056a963164098/src/Illuminate/Translation/Translator.php#L317-L350
  3. Create :resource and Update :resource are used in \Laravel\Nova\Resource::createButtonLabel and \Laravel\Nova\Resource::updateButtonLabel don't utilise values from (1) but instead use (2)
  4. Octane only flush parsedKey between operation. So (2) persist between request. https://github.com/laravel/octane/blob/253d8aeea6de74f52da8d466a4c51e7160fe050e/src/Listeners/FlushTranslatorCache.php#L21-L25

Potential solutions

I would recommend adding an event to flush loaded translation for Octane (not sure what's the side affect are to PR this to Octane right now).

$translator = $event->sandbox->make('translator');
$translator->setLoaded([]);

Alternatively, if you need it for your application, then you need to register it in your application service provider explicitly:

this->loadJsonTranslationsFrom(lang_path('vendor/nova'));

@kichetof
Copy link
Author

Hi @crynobone,

Many thanks for your time and all your knowledge! It's really appreciated.

I forget to mention that only these 2 keys are not translated. I've a doubt about translator flush issue

Image

I write this TrueCheck with Nova::__ as it trigger my issue like my prod application, but I need to double check on my prod application if I call Nova::__ outside of Nova path (maybe an additional package 🧐). For sure, we have our external ping service who call a health endpoint and our internal API, nothing call Nova::__

I'll try this weekend to trigger this issue without calling Nova::__ and update the repo. I'll keep you in touch.
Thanks a lot

@crynobone
Copy link
Member

Nova::__() just hold the original key and do the replacement when the instance need to be cast to string (typically on response etc) so that locale doesn't not get resolved immediately. It still rely on __() under the hood.

@kichetof
Copy link
Author

kichetof commented Apr 26, 2025

Okay you're right! Issue come from translator loaded cache.

I set 2 endpoints: reload worker between tests

  • /trigger who displays a translation key. Visit it and go to Nova --> translation issue.
  • /test who displays 2 Nova translation keys without loading it in my service provider (with this->loadJsonTranslationsFrom(lang_path('vendor/nova'));). Visit it (keys not translated as expected) and go to Nova --> Create & Add Another is translated as expected but not Create :resource

Now, uncomment https://github.com/kichetof/nova-octane-docker/blob/6cf9abdf6f6a01cea4f68122966a7bd9252f7e5f/config/octane.php#L77 who will flush translator loaded as you mention it. Reload worker and everything is displayed correctly.

For my knowledge, I try to understand why only both keys Create :resource and Update :resource aren't translated as expected without flushing loaded cache. Ok I found it! Other translations come from js resources/js/util/localization.js function __ and as you mentioned, from Nova::$translations

Regarding a potential solution

Should Nova need to register translations regardless if Nova is currently serving or not ? As Translations are cached, when you come from outside Nova, you'll lose these 2 translations. Or fix how these keys are resolved?

Thanks for your help!

@crynobone crynobone added bug Verified bug by the Nova team fix incoming A fix is in review labels Apr 28, 2025
@crynobone
Copy link
Member

Should Nova need to register translations regardless if Nova is currently serving or not ?

Done in 5.6.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Verified bug by the Nova team fix incoming A fix is in review
Projects
None yet
Development

No branches or pull requests

2 participants