Vue.js and Twig (in Symfony)

Dariusz Włodarczyk
4 min readMar 29, 2021

After finishing my project almost fully written as SPA (Single Page Application) by using Vue.js as frontend and Symfony as Backend, I’ve decided to grab one of my projects and continue exploring Vue.js (memorizing and learning more about it).

This time however I wanted to give a try to other approach:

  • using Vue.js as a wrapper for frontend (which means that the frontend logic was/is suppose to be controlled by Vue),
  • Symfony is being used used as a backend alongside with rendering the templates in Twig

The long story short — does it work?

While the simple answer is yes — it is working, the long answer is it’s troublesome, with workarounds, headaches and resignations.

Handling Vue variables in Twig

The frontend can be controlled by Vue, the communication with twig rendered DOM is possible. The Vue variables can also be used alongside with Twig variables, but this requires a small configuration (which either is handled on every Vue instance or is configured globally) like this:

With this Vue variables can be used in Twig

Vue syntax readability / IDE mixed syntax support

Now if You take a look on the example above the <sweet-alert> Vue component is added to the Twig file. I’m using PhpStorm with Symfony plugin and it supports mixed syntax up to some degree. While Twig/Symfony syntax works the way it usually does, I cannot say the same about the Vue.js syntax.

In the best case if the base.twig contains a component which is then has a Vue app created for one of the elements — then it generally works fine like for example the methods are colored and can be navigated, and naturally PhpStorm does recognize the Vue specific syntax like for example @click.prevent="" however that’s pretty much it when it comes to syntax readability.

There are rather more downsides to this solution, but shortly:

  • there is no way to highlight or navigate to the Vue variables in Twig template,
  • upon including another Twig template (with more Vue components) in my base.twig like below (dialogs/manage-search-settings.twig contains another component), the deeper component variables, and methods were not working in given component — the parent component (attached to #jobSearchMainContent) had intercepted the logic calls
  • using Vue calls alongside with rendered Forms make the code unreadable and impossible to navigate, additionally in Vue the methods are never highlighted as being used

Rendering issues

The most annoying thing which actually made me take a deep breath and caused me to think “I’m having enough of this mess” was the rendering issue, where adding table rows via component causes the rendered output to be displaced like below:

Displaced rows in table

Colliding components

Based on the example in current rewriting attempt. Let’s say we we have this in twig<div id="componentA"><div id="componentB></div></div> .

Now upon creating the Vue app on the componentA everything works fine, but upon adding additional Vue file for the componentB suddenly the logic of componentB is no longer working, causes exceptions and like already mentioned componentA will intercept calls from componentB.

The workaround for this is setting all the logic inside the componentA which makes the code a bit messy, or even very messy as the logic of 2 components is mixed up together.

Ajax page content reloading

I wanted to load the page content into one container via ajax calls (like i did in my other projects). This solution is causes even more issues with the Vue since I’m adding on each page the<script> tag with compiled code, but — since the code is loaded via ajax the content of the script must be executed upon reload, and this requires more workarounds like loading and executing the loaded scripts:

Summary

Simply saying, I will most likely abandon my idea of handling template rendering via Twig as this is becoming more and more frustrating, there are more workarounds present in my code:

  • EncoreService — to handle extracting bundle scripts compiled by Webpack,
  • Scripts sources — passed to the twig to execute them later on via js ajax call,
  • Preconfigured Axios — as Symfony does not recognize Axios calls as ajax calls, and since I need to distinguish the ajax call from normal call then this is a must,
  • Moving twig templates to the Vue — regarding the issue with modal (mentioned above),

Personal opinion

Based on my experience with combining Vue with Symfony:

  • Vue works fantastic when the templates are being handled by Vue itself via One File Component, this naturally requires a lot of Symfony Api calls but works like a charm,
  • Vue combined with Twig causes more and more issues, the longer I work with it the more I want to close the project.
  • Attaching Vue components to the Vue but as One File Component might also work very well since Vue will handle the component template alone, executing calls to the backend,

--

--

Dariusz Włodarczyk

Hobby frontend / backend developer — author of Personal Management System. https://git.io/JePh1. You can find me also here: https://ko-fi.com/volmarg.