How to use laravel-vue-i18n to change translations in laravel blades also? - laravel

Can anyone help me make translations working in laravel blades too?
I need to change/translate the contents of the title and description meta depending on the language being switched.
This is how the language changes in Vue:
<template>
<ul class='language-switcher'>
<li :class="{'active': language === 'de'}">
De
</li>
<li :class="{'active': language === 'en'}">
En
</li>
</ul>
</template>
<script>
import {loadLanguageAsync} from "laravel-vue-i18n";
export default {
name: "LanguageSwitcherComponent",
data() {
return {
language: 'en',
};
},
methods: {
switchLanguageTo(lang) {
// ...
loadLanguageAsync(lang);
// ...
},
},
}
</script>
In Vue, the translations work fine, but I need to translate title and description meta in index.balde.php as well.
<!DOCTYPE html>
<html lang="{{str_replace('_', '-', app()->getLocale())}}">
<head>
<title>{{ __("Site Title") }}</title>
<meta name="description" content="{{ __("Site Info") }}">
<meta charset="utf-8">
<meta name="csrf-token" content="{{ csrf_token() }}"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{{mix('css/app.css')}}">
</head>
<body>
<div id="app">
<index-component/>
</div>
<script src="{{mix('js/app.js')}}"></script>
</body>
</html>
Also, this is how configured i18n in app.js:
import {i18nVue} from 'laravel-vue-i18n';
// ...
app.use(i18nVue, {
lang: 'en',
resolve: lang => import(`../../lang/${lang}.json`),
});
Thanks!

Save site language in cookies and in web.php set locale from cookies.
Route::get('/{any}', function (Request $request) {
// Set locale
App::setLocale($request->cookie('site_language') ?: 'en');
return view('index');
})->where('any', '.*');
Note: Maybe will need to add cookie name in app/Http/Middleware/EncryptCookies.php in $except list to get cookie from the $request successfully.

Related

Vue 3 router with Laravel

I am new to Vue JS and I installed vue 3 with laravel and it shows 404 Not Found. I tried a lot but could not find out the issue.
app.blade.php
<div class="min-h-screen bg-gray-100" id="app">
<!-- Page Content -->
<main>
{{ $slot }}
</main>
</div>
app.js
import { createApp } from "vue";
import router from './router'
import CompaniesIndex from './components/companies/CompaniesIndex'
createApp({
components: {
CompaniesIndex
}
}).use(router).mount('#app')
index.js
import { createRouter, createWebHistory } from "vue-router";
import CompaniesIndex from '../components/companies/CompaniesIndex'
const routes = [
{
path: '/welcome',
name: 'companies.index',
component: CompaniesIndex
},
]
export default createRouter({
history: createWebHistory(),
routes
})
ComponiesIndex.vue
<template>
Hello world
</template>
<script>
export default {
}
</script>
web.php
Route::get('/{any}', function () { return view('app'); })->where('any', '. *');
welcome.blade.php
<body class="antialiased">
<h1>Welcome to Laravel Vue 3</h1>
</body>
I'm not sure, but there is maybe an error in your routes/web.php in where statement, because . * regex should match any string and this is .* without whitespace. Please try:
Route::view('/{any}', 'app')->where('any', '.*');
If you are creating SPA your app.blade.php should not contain any markup, it should be blank HTML template with required script with your app:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<script src="{{ mix('assets/js/app.js') }}" defer></script>
<link href="{{ mix('assets/css/app.css') }}" rel="stylesheet">
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
Then you just mount your Vue app to #app div, which seems to be good in your app.js.

Change laravel html lang variable

I have laravel/VueJs app which is supporting multiple language but there is one issue, when I change language on VueJs html Lang tag will not change.
Code
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" content="{{ csrf_token() }}" />
<title>{{ config('app.name', 'Laravel') }}</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet" />
<style>body{ margin-bottom: 60px !important;}</style>
</head>
<body style="overflow:hidden;">
<noscript>
<strong>We're sorry but Xtreme Vuesax doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script src="{{ asset('js/app.js') }}"></script>
<script>
window.default_locale = "{{ config('app.locale') }}";
window.fallback_locale = "{{ config('app.fallback_locale') }}";
</script>
</body>
</html>
app.js
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
import localesData from './components/Layouts/localesData'
Vue.component('locale-dropdown', require('./components/Layouts/locales').default);
const i18n = new VueI18n({
locale: 'en',
messages: localesData,
})
const app = new Vue({
el: '#app',
router,
store,
i18n,
render: h => h(App)
});
Explanation
I need this line <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> to be change to selected language in VueJs.
any idea how to change that?
From within your Vue component 'locale-dropdown', when the user selects a locale, you can
//say the data property on your component which holds the selected locale is called locale
let h = document.querySelector('html');
h.setAttribute('lang', this.locale);

How to setup inertia on my project, gives me an error when I try and load the login page

I'm trying to setup Inertia to use in my Laravel project but it gives me errors? Where is my mistake?
I installed Inertia with this command
composer require inertiajs/inertia-laravel
followed the instructions on the github page and added #inertia to my app.blade.php like this:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<link rel="icon" type="image/jpg" href="{{asset("/image/logo2.png")}}">
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
#inertia
</body>
</html>
in my Login Controller
public function showLoginForm()
{
return Inertia::render('Auth/Login');
}
in my routes/web.php
Auth::routes();
Route::get('login', 'Auth\LoginController#showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController#login');
This is the error I get:
the lines that is highlighted is the #inertia which show up as this
<div id="app" data-page="<?php echo e(json_encode($page)); ?>"></div>
What am i doing wrong?
#inertia blade directive is working but not rendered because you need to install the frontend adapter
npm install #inertiajs/inertia #inertiajs/inertia-vue
Set it up in webpack.mix.jsĀ 
const mix = require('laravel-mix')
const path = require('path')
mix.js('resources/js/app.js', 'public/js')
.webpackConfig({
output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
'#': path.resolve('resources/js'),
},
},
})
And initialize it in Vue resources/js/app.js
import { InertiaApp } from '#inertiajs/inertia-vue'
import Vue from 'vue'
Vue.use(InertiaApp)
const app = document.getElementById('app')
const pages = {
'Auth/Login': require('./Pages/Auth/Login.vue').default,
}
new Vue({
render: h => h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name => pages[name],
},
}),
}).$mount(app)

Is there an issue retriving json data when using vue, axios, and laravel?

I am trying to replicate a tutorial on vuecasts (https://laracasts.com/series/learn-vue-2-step-by-step/episodes/18).
Everything looks fine and I don't get any errors except a warning:
Resource interpreted as Document but transferred with MIME type
application/json: "http://vueme.app:8000/skills"
I already tried to change content-type to text/html as suggested here:
Resource interpreted as Document but transferred with MIME type application/json warning in Chrome Developer Tools
web.php:
Route::get('/', function () {
return view('welcome');
});
Route::get('skills', function(){
return ['javascript', 'php', 'python'];
});
welcome.blade.php:
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<title>Laravel</title>
</head>
<body>
<div id="root">
<ul>
<li v-for="skill in skills" v-text="skill"></li>
</ul>
</div>
<script scr="https://unpkg.com/axios/dist/axios.min.js"></script>
<script scr="https://unpkg.com/vue"></script>
<script scr="/js/app.js"></script>
</body>
</html>
app.js:
new Vue({
el: '#root',
data:{
skills:[]
},
mounted(){
axios.get('/skills').then(response => this.skills = response.data);
}
});
What's not working?

Blade Template with comment on top not working

file: app/route.php
Route::get('/', function()
{
return View::make('home');
});
file: app/views/home.blade.php
{{-- Blade comment. --}}
#extends('layouts.base')
#section('head')
<link rel="stylesheet" href="second.css" />
#stop
#section('body')
<h1>Heading</h1>
<p>Hello Home!</p>
#stop
file: app/views/layouts/base.blade.php
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
#section('head')
<link rel="stylesheet" href="style.css" />
#show
</head>
<body>
#yield('body')
</body>
</html>
When I access to laravel.localhost/
It only output
#extends('layouts.base')
but however, if I remove the
{{-- Blade comment. --}}
then it works perfectly.
May I know what is the issue?
The first line in your extended blade view must be the #extends directive.
Yes it is a convention by the devs.
Look at BladeCompiler.php on line 119.
protected function compileExtends($value)
{
// By convention, Blade views using template inheritance must begin with the
// #extends expression, otherwise they will not be compiled with template
// inheritance. So, if they do not start with that we will just return.
if (strpos($value, '#extends') !== 0)
{
return $value;
}

Resources