Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

shuch3n's avatar

Use trans in vue.js

Hi,

Atm i'm using vue.js component with vueify compiler. How can I translate something in template using Laravel trans methods

Thanks,

Shu

0 likes
30 replies
Juukie's avatar

I guess you can't because you can't execute PHP in your .vue file. You could create a method that will send a xhr request to get a translation but that would result in many requests.

1 like
shuch3n's avatar

Thanks for your suggestion, I moved the template to my blade ;)

cipsas's avatar

Yes, laravel (PHP) is server side, and you can't use it directly into javascript You can create own trans() function in vuejs and import translations in json format

crispunkrock's avatar

Yes, it is partially possible, just converting the translation array to Json and save this in js variable, afther that you can use this variable (Json transalations) in vue js.

For example :

wellcome.blade.php { var transJson = {!! json_encode(trans('categories')) !!}; var translations = JSON.stringify(transJson);

}

master.js (vue script) {

console.log(translations); }

3 likes
tomasbedrich's avatar

In case someone is still interested, I have solved the problem this way:

Open your base app template (probably resources/views/layouts/app.blade.php) and add this to the header:

    <script>
        window.trans = <?php
        // copy all translations from /resources/lang/CURRENT_LOCALE/* to global JS variable
        $lang_files = File::files(resource_path() . '/lang/' . App::getLocale());
        $trans = [];
        foreach ($lang_files as $f) {
            $filename = pathinfo($f)['filename'];
            $trans[$filename] = trans($filename);
        }
        echo json_encode($trans);
        ?>;
    </script>

Then, extend the Vue prototype by the following to method (in your app.js):

Vue.prototype.trans = (key) => {
    return _.get(window.trans, key, key);
};

Then, you can use trans() function in your Vue templates!

{{ trans('orders.add') }}
24 likes
maxdiable's avatar

sorry, I would like to use your technique with this

'gte' => [ 'numeric' => 'The :attribute must be greater than or equal :value.', 'file' => 'The :attribute must be greater than or equal :value kilobytes.', 'string' => 'The :attribute must be greater than or equal :value characters.', 'array' => 'The :attribute must have :value items or more.', ],

it's possible?

br Max

sweijdt's avatar

@tomasbedrich, interesting approach. I was thinking to use the laracast Javascript package to send the translations to the view. I'm also using Vuex now. I'm not sure what the best approach is yet.

Quezler's avatar

@sweijdt i am getting

TypeError: _.get is not a function

any idea what i did wrong?

cleopatria's avatar

@tomasbedrich I use this

{{  trans('menus.about') }}

in my vue component. But It doesn't display the content, it dispalys menus.about intead. How to fix it?

kJamesy's avatar

Thanks @tomasbedrich for the solution. Works perfectly for me. I have to add a little method in my Vue script in order to translate strings inside the javascript (as opposed to the template)

translate(key) { return _.get(trans, key, key); }

PeerGum's avatar

Been facing that requirement too.

Although several solutions offered worked fine, I wonder if it's not easier to have both the JS and PHP (lang) files statically generated by some code server-side each time messages are updated.

Two benefits: less time/cpu-consuming + you can generate everything from easier to update files for non-technical people (plus avoid the risk of someone putting harmful stuff in the files).

Going to go that way, possibly feeding JS+PHP from PO files...

aurawindsurfing's avatar

I have a different approach. Since in most of the cases we are talking about static transaltions while using VueJS the simplest thing is to move what has to be translated outside of Vue script into blade template. Here is the example of my original code:

Vue.component('vue-google-autocomplete', {

    template: `
    <input
        ref="autocomplete"
        name="locality"
        type="text"
        required="required"
        :class="classname"
        :id="id"
        :placeholder="Start typing name or postal code..."
        v-model="autocompleteText"
        @focus="onFocus()"
        @blur="onBlur()"
        @change="onChange"
        @keypress.enter.prevent="onKeyPress"
     >
`,

and in blade

<vue-google-autocomplete></vue-google-autocomplete>

Then I figured out that the simplest thing to do will be to move placeholder outside of vue like so:

Vue.component('vue-google-autocomplete', {

    template: `
    <input
        ref="autocomplete"
        name="locality"
        type="text"
        required="required"
        :class="classname"
        :id="id"
        v-model="autocompleteText"
        @focus="onFocus()"
        @blur="onBlur()"
        @change="onChange"
        @keypress.enter.prevent="onKeyPress"
     >
`,

and blade will then look like this including transaltion:

<vue-google-autocomplete placeholder="{{__('Start typing name or postal code...')}}"></vue-google-autocomplete>

As you can see i'm using strings as keys for translation. Simple solution and it works.

hcivelek's avatar

I use this simple method.. it works like blade..

         var appMenu = new Vue({
            el: '#app-menu',
            data: {
                menuitems:{!! $menuitems !!}},
                lang:{
                    menu:{!! json_encode(__('menu')) !!},
                    something:{!! json_encode(__('something')) !!}
                }
            },
            methods:{   
                __:function(key)
                {

                    if (key.match(/\./))
                    {
                        var str = key.split(".")

                        if (typeof this.lang[str[0]] !== "undefined" && typeof this.lang[str[0]][str[1]] !== "undefined")
                            return this.lang[str[0]][str[1]]
                        else
                            return key
                        
                    }
                    else
                        return key;

                }
            }
        });

I can use it like this:

<li v-for="item in menuitems">
@{{__(item.name)}}
</li>

Of course we can seperate __() function to use every where..

bbdangar's avatar

I have done this by using props: ['lang'].

And while using component,

<register lang="{{ json_encode(__('register')) }}"> </register>

1 like
codebyjeff's avatar

Regarding:

TypeError: _.get is not a function

You may need to import _ from 'lodash'; above the Vue.prototype.trans code

alessandrobelli's avatar

Not sure if this is still a thing, but in my case I used

Vue.prototype.trans = (key) => {
    return window.trans[_.findKey(window.trans,key)][key];
};

to first get which file included the key pair and then return the correct key.

marco8757's avatar

We have our keywords nested with dots

like in our keyword.php

we have

'product-page.title' => 'Product :test',
'product-page.action.share' => 'Share',

hence the trans('keyword.product-page.action.share') wouldnt work

just wanna share my two cents of how i made this work:

Vue.prototype.trans = (key) => {

    let file_prefix = key.substr(0,key.indexOf('.'));
    let keyword_suffix = key.substr(key.indexOf('.')+1);
    let result = window.trans[file_prefix][keyword_suffix];

    if (result === undefined){
        return key;
    } else {
        return result;
    }
};
rahullodhi's avatar

@tomasbedrich I have set it as it is like you have commented on your answer but getting this error on

Vue.prototype.trans = (key) => { return _.get(window.trans, key, key); };

Cannot set properties of undefined (setting 'trans')

Please or to participate in this conversation.