skip to Main Content

I’m working on a project using Symfony 7.1 and PHP 8.3. I’ve encountered an issue with the AssetMapper where my JavaScript files only load on the initial page load or after an F5 refresh. When navigating between pages, the JS files do not load correctly.

For example, I have installed DataTables.net with AssetMapper. Everything works fine on the first page load, and my DataTable is properly initialized

enter image description here

However, if I navigate away from this page and then return, the DataTable is no longer initialized because the JS file is not being called again.

enter image description here

In this example, I used DataTables, but I experience the same issue with my own custom JS files.

Steps Taken:

  • Followed the Symfony documentation for installing and configuring AssetMapper.
  • Ensured that DataTables.net is correctly set up and working on the initial page load.
  • Checked for any errors in the browser console.

Code Snippet (app.js):

import './styles/app.css';
import 'datatables.net-dt/css/dataTables.dataTables.min.css';

import './bootstrap.js';
import DataTable from 'datatables.net-dt';


function loadDatatable() {
    console.log( '%c loadDatatable', 'background: #00FF2E; color: #000000' );
    new DataTable( '#users-datatable', {
        ajax:       Routing.generate( 'app_users_ajax' ),
        processing: true,
        serverSide: true,
        columns:    [
            { data: 'id' },
            { data: 'email' },
            { data: 'firstName' },
            { data: 'lastName' },
            { data: 'status' },
            {
                data:   'action',
                render: function ( data, type, row ) {
                    return `<a href="/?_switch_user=${ row.email }" class="font-bold w-full rounded my-1 bg-primary text-white text-primary-foreground hover:bg-primary-hover py-2 px-3">Impersonate</a>`;
                },
            },
        ],
    } );
}

document.addEventListener( 'DOMContentLoaded', function () {
    loadDatatable();
} );

base.html.twig

{% block javascripts %}
    {% block importmap %}
        {{ importmap('app') }}
    {% endblock %}
{% endblock %}

Error Message:

No specific error messages are displayed in the console when navigating back to the page.

Symfony and PHP Versions:

Symfony version: 7.1
PHP version: 8.3

Thank you for your help!

2

Answers


  1. Chosen as BEST ANSWER

    I have found a solution to my problem based on the comments from 537mfb on this issue.

    No - what is in my answer is the one solution that worked for me - maybe you could remove @hotwired/turbo and @hotwired/stimulus if you're really not going to take advantage of them, but I haven't tried that and can't say if there will be any other consequences from removing them

    To be clear - I believe @hotwired/turbo specifiacally is responsable for this behaviour of code set to run on DOMLoaded only running on first page load - unless the page has a different entrypoint from importmap

    Here's what I did to resolve the issue:

    1. I removed symfony/ux-turbo from my project:

      composer remove stimulus-bundle
      
    2. I also removed the following references for AssetMapper:

      php bin/console importmap:remove @hotwired/stimulus
      php bin/console importmap:remove @hotwired/turbo
      php bin/console importmap:remove @symfony/stimulus-bundle
      
    3. In my app.js file, I removed this import:

      import './bootstrap.js';
      

    After making these changes, my JS files load correctly with each navigation, and I no longer experience the issue.

    I am not sure about potential side effects, as I haven't dug deeper into this and my project isn't very large.

    Thanks to 537mfb for the helpful information!


  2. I had similar error, and after some research, I found that Turbo UX is designed to avoid full page reloads. However, including custom JavaScript files may require some care. For instance, if your JavaScript code interacts with parts of a page that can be dynamically updated by Turbo, make sure your script runs at the right time.

    To ensure that Turbo doesn’t prevent your script from running, you can use events like turbo:load or turbo:frame-load to trigger your JavaScript:

    document.addEventListener("turbo:load", function() {
        // Your JS code that should run after a full page load
    });
    

    If you want the code to execute whenever a frame is loaded:

    document.addEventListener("turbo:frame-load", function() {
        // Your JS code that should run every time a frame is updated
    });
    

    This way, Turbo won’t stop your custom JavaScript from running even during partial page transitions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search