xiCO2k / laravel-vue-i18n

Allows to connect your `Laravel` Framework translation files with `Vue`.
MIT License
594 stars 49 forks source link

Translations not working inside layout (App.vue) #93

Closed haztakki closed 1 year ago

haztakki commented 1 year ago

Hello @xiCO2k, Great package! It works really well, I have been using it for my upcoming project and it's been a breeze. Though I am running into a weird issue that I'm not sure how to solve. Translations don't seem to be working inside a layout (including nested components within). Everything inside the <slot /> seems to work perfectly. I have a feeling it's something to do with how I am using layouts with Inertia.

<!-- other relevant imports -->
import { i18nVue } from "laravel-vue-i18n";

createInertiaApp({
    resolve: (name) => {
        const page = resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob("./Pages/**/*.vue"));

        page.then((module) => {
            module.default.layout = module.default.layout || BaseLayout;
        });

        return page;
    },

    title: (title) => (title ? `${title} - App Name` : "App Name"),

    setup({ el, App, props, plugin }) {
        createApp({ render: () => h(App, props) })
            .mixin({ methods: { route } })
            .use(plugin)
            .use(i18nVue, {
                lang: "fi",
                resolve: async (lang) => {
                    const langs = import.meta.glob("../../lang/*.json");

                    return await langs[`../../lang/${lang}.json`]();
                },
            })
            .mount(el);
    },
});

The same translations that work elsewhere don't work here.

My App.vue just contains the usual boilerplate code (nav, global search, etc) so I won't paste it here.

<!-- lots of boilerplate code -->
<slot />

What's weird is that for pages that use the default layout (Base.vue), the translations work just fine.

I did some more digging... Could it be related to the workaround?

<script>
    import AppLayout from "@/Shared/Layouts/App.vue";

    export default {
        layout: AppLayout,
    };
</script>
<script setup>
...

https://github.com/inertiajs/inertia/discussions/651

Maybe you could give some light on this.

xiCO2k commented 1 year ago

Hey @HazJ will investigate that ASAP

kovinet commented 1 year ago

I am having the same issue. On page load translations inside Vue Layout are not working, but if I click somewhere on a link so that the same page is loaded via Inertia router, then translations load).

image

xiCO2k commented 1 year ago

Hey @HazJ did you already try this with inertia v1?

haztakki commented 1 year ago

Hello, Not yet. I will try it soon. I didn't see anything in the v1 changelog that would have an affect on this. I could be wrong though. I'll keep you posted.

xiCO2k commented 1 year ago

Yea me too, I don't think it should affect.

Also if you want to try fix this, I would be glad to review it.

Thanks.

On Sat, Jan 21, 2023 at 9:00 PM Haz @.***> wrote:

Hello, Not yet. I will try it soon. I didn't see anything in the v1 changelog that would have an affect on this. I could be wrong though. I'll keep you posted.

— Reply to this email directly, view it on GitHub https://github.com/xiCO2k/laravel-vue-i18n/issues/93#issuecomment-1399331657, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGI6MCIRJMSF4SY36HGHDLWTRE6TANCNFSM6AAAAAATJ3RK5U . You are receiving this because you were mentioned.Message ID: @.***>

haztakki commented 1 year ago

It made no difference. I'll try to spend some time looking into it.

e4se commented 1 year ago

@HazJ do u find any solution how to fix it?? I have the same problem.

nickvleeuwen commented 1 year ago

For me the problem only occurred on initial page load just like @kovinet . I think this was because the translations where loaded after vue had mounted the page.

When logging something inside the onMounted callback of vue, and logging something inside the onLoad callback of this package, the onMounted log was shown first.

What I ended up doing was mounting the vue instance inside the onLoad callback of this package. I hope I don't destroy something by doing it this way :).

const app = createApp({ render: () => h(App, props) });

return app
.use(i18nVue, {
    resolve: async lang => {
        const langs = import.meta.glob('../../lang/*.json');
        return await langs[`../../lang/${lang}.json`]();
    },
    onLoad: () => {
        app.mount(el); // Mounted here so translations are loaded before vue.
    }
});

Maybe this comment helps some people that are having the same issue.