How to use Vue.js Router with Server Side templates for Vue components

So I hit a slight snag today, I was wandering wouldn’t it be great if my latest project could rely on Javascript more and even be a one page app written in Vue.JS. One of the biggest problems with client side apps for me is still translations. As primarily a PHP developer myself I’ve not had to focus on this too much because well, I don’t do Javascript often and often use frameworks like Laravel where translation mechanisms are baked in and well documented. At the same time, I have to still translate form validation errors, emails and notifications on the server side, so doesn’t it make sense to just keep using the Server Side?

The problem with Javascript is well, how do you do it? Create a server side resource for the browser to pull into the application? A big ol’ json file for each language? Seems a bit overkill. At the same time, if you’ve created a Vue component before and used something like webpack to bundle it all into your JS you’ll know that this content will be essentially static. I dread to think how you’d implement something to download the translations and apply them to all of your components. I’m still getting to grips with Node.js at times (although if you know a good way please do tell me).

What can you do then without loosing the best of both? well with a bit of research it’s actually quite simple. Template tags!

I’ve made a fiddle that illustrates how this works. You can easily fork it and have a little play around but the basics of it are below.

So firstly pay attention to the components created in the Javascript:

const Foo = { template: ‘<div>foo</div>’ }
const Bar = { template: ‘#bar’ }

Bar doesn’t use a HTML template like Foo does, instead it will reference the id attribute of a template tag in our HTML page.

That template in our HTML looks like this:

<template id="bar">
<div>bar</div>
</template>

We have to make sure this sits outside the div tag for the app e.g. it shouldn’t sit inside <div id="app"></div> or it just won’t work. Don’t worry either, that template won’t show up on the page.

So this is static but what if we were using Laravel? Well we can just use our good old Blade syntax as normal:

<template id="bar">
<div>@lang('messages.bar')</div>
</template>

This way the server side will generate the right template for the language before outputting it to the user’s browser.

What’s the catch?

Well as with most things, this doesn’t come without some potential issues to think about. Namely caching, how do you keep your javascript and server side code synced? We have to think about some complex problems, having all the template compiled and minified in a Javascript file is simple to cache for the most part and when you’re writing a one page app, caching like this it’s a big performance boost. If you’re making requests against your server side API and a user’s browser has a cached version of the Javascript application, the worst that will happen is that it won’t be able to act correctly but most developers take this into account when they develop client side applications. Developers typically check for HTTP statuses like 404 and 500 so the app knows that the backend and frontend aren’t working together.

But what if we cache the Javascript and the HTML from the server side (for improved download speeds)? Well there’s a lot of risk in the client application code having a newer or older template for it’s components. My best advice currently is you should definitely be making sure that when a user loads a page it includes via a different URI for each new version of the javascript when it’s packed up e.g. app-1234.js rather than simplyapp.js.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.