What to do, when your backend templating engine is getting in the way of your frontend framework?
That’s what happens if you’re trying to mix Vue.JS and Django - both are using curly brackets by default, and it’s easy to run into issues by accident. It’s as simple, as forgetting that the two can clash in the first place.
Then you’re stuck wondering, why the variable seems to be an empty string in Vue, while the Django template went ahead and replaced it before Vue was around.
Two ways around that
There are two ways, you can use to help Vue and Django play nicely in your templates.
- You can tell Vue to use another delimiter instead of
{{ and }}
- You can tell Django to stay away from your Vue templates with
{% verbatim %}
If you want to avoid having to adjust any snippet you’re using from the web towards new delimiters, the verbatim
approach will make your life easier.
Also, you won’t run into issues when you forget to adjust those curly brackets into square ones by accident. Those bugs are unnecessarily confusing to debug.
Verbatim!
Wrap your Vue templates in {% verbatim %}
tag blocks, so it’s not interpreted by Django. Simply put a verbatim
tag around any place where Django should not interfere, and you’re set!
Usually, you’ll want to wrap:
- The HTML element mounting point of your Vue app which might contain some Vue templating (you might be using
id="app"
for example) - The script block where a new Vue app is created
- Any script blocks where you’re defining Vue components
Here’s a very brief example:
<script>
// this is NOT wrapped in a verbatim block
// as we need Django to render out some data as JSON
let data = {{ data | safe }};
</script>
(...)
{% verbatim %}
<!-- we protect this Vue templates :) -->
<script type="text/x-template">
(...)
</script>
{% endverbatim %}
(...)
{% verbatim %}
<div id="app">
<!-- the Vue mounting point is safe -->
(...)
</div>
{% endverbatim %}
(...)
{% verbatim %}
<script>
var app = new Vue({
el: '#app',
// this Vue templates will not be affected by Django thanks to verbatim
(...)
</script>
{% endverbatim %}
(...)
This will help you to make sure, that your Vue templates are clearly separated from the rest of the Django template, and there’s very little room for losing time through silly mistakes.
If you need to pass data to Vue from your Django template, you should do so at a well-defined place in the template. Create an additional script tag and render the data out into a simple JS variable in a script block which is explicitly not wrapped in a verbatim
block.