Search code examples
twigsymfony7

Template not updating language direction when changing language


In base.html.twig, I have the following:

<html lang="{{- app.request.locale -}}" dir="{{- app.request.locale|locale_dir -}}">

Where locale_dir is a custom Twig filter that returns ltr or rtl depending on the locale. Then I have a controller with a route using /{_locale}/ as path, and a small menu with languages to change around.

If I input in the address bar https://localhost:8000/en/, I get an english page with the HTML tag as:

<html lang="en" dir="ltr">

If I input in the address bar https://localhost:8000/ar/, I get an arabic page with HTML tag as:

<html lang="en" dir="rtl">

However, if I input the english page address and then use the menu to change to arabic, I get the arabic page with the HTML tag as:

<html lang="ar" dir="ltr">

And if I input the arabic page address and then use the menu to change to english, I get the english page with the HTML tag as:

<html lang="en" dir="rtl">

I've placed a log entry in my custom Twig filter, and I can tell that when changing language with the menu, my filter is getting called for the HTML tag, is returning the correct value, but the tag's dir argument isn't beeing updated.

I'm guessing Symfony doesn't really reload the all page when following a link, but rather makes some sort of Ajax call (or similar) to get the content, and updates the lang argument but not the dir argument of the HTML tag?

What am I missing?

EDIT: Just tested with fiddler open to see what happens: When changing the language using the menu, fiddler detects a normal GET request with the full page as a response. And in that response, the dir argument has always the correct value:

<html lang="en" dir="ltr">

and

<html lang="ar" dir="rtl">

However, the DOM itself doesn't update the dir argument as expected:

<html lang="ar" dir="ltr">

EDIT 2 Here's video of what I mean by symfony updates the body and lang argument but leaves the dir argument with it's first value

Symfony not updating dir argument

As I said, I confirmed in fiddler that the response from the server comes with the correct value in dir

EDIT 3: created a git repo with minimal testing at https://github.com/537mfb/dir_test


Solution

  • I've solved this by adding an extra entrypoint in importmap.php that I use exclusivelly on rtl languages.

    EDIT: After further inspection I've realized that now with the new entrypoint added, there are two consecutive GET requests beeing performed now.

    The differences in the headers of the two requests are:

    Request 1:

    accept: text/html, application/xhtml+xml
    x-sec-purpose: prefetch
    x-turbo-request-id: 701c1632-41bd-4694-a309-e937451645ed
    Sec-Fetch-Mode: cors
    Sec-Fetch-Dest: empty
    

    Request 2:

    Upgrade-Insecure-Requests: 1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    

    So I'm guessing @hotwired/turbo (wich comes installed with symfony's full install - using --webapp) is responsable for the issue I was seeing.

    still - not ideal to have 2 GET requests - both returning the full page, but at least it's working.