xiCO2k / laravel-vue-i18n

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

Console error in Firefox #80

Closed xiki808 closed 1 year ago

xiki808 commented 1 year ago

Hi, I'm getting the following error when on Firefox. No issues on Chrome

Uncaught (in promise) TypeError: langs[(("../../lang/" + (intermediate value)) + ".json")] is not a function

image

xiki808 commented 1 year ago

Would like to also add, that even though the error is produced, translations still work.

xiCO2k commented 1 year ago

Hey @xiki808 can you show me you app.js file to help debugging the issue?

Thanks

xiki808 commented 1 year ago

Hi @xiCO2k, here's my app.js

import './bootstrap';
import '../css/app.css';

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from 'ziggy';
import { i18nVue } from 'laravel-vue-i18n';

const appName =
  window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';

createInertiaApp({
  title: (title) => `${title} - ${appName}`,
  resolve: (name) =>
    resolvePageComponent(
      `./Pages/${name}.vue`,
      import.meta.glob('./Pages/**/*.vue')
    ),
  setup({ el, app, props, plugin }) {
    return createApp({ render: () => h(app, props) })
      .use(plugin)
      .use(ZiggyVue)
      .use(i18nVue, {
        resolve: async (lang) => {
          const langs = import.meta.glob('../../lang/*.json');
          return await langs[`../../lang/${lang}.json`]();
        },
      })
      .mount(el);
  },
});

InertiaProgress.init({ color: '#3265EA' });

In case it helps, I'm using Laravel version 9 with Vite. Here's my Vite config:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import eslintPlugin from 'vite-plugin-eslint';
import i18n from 'laravel-vue-i18n/vite';
import fs from 'fs';

export default defineConfig({
  server: {
    hmr: {
      host: 'localhost',
    },
    host: '0.0.0.0',
    port: 1882,
    https: {
      key: fs.readFileSync('./.docker/images/nginx/ssl/localhost.key'),
      cert: fs.readFileSync('./.docker/images/nginx/ssl/localhost.cer'),
    },
  },
  plugins: [
    laravel({
      input: 'resources/js/app.js',
      refresh: true,
    }),
    vue({
      template: {
        transformAssetUrls: {
          base: null,
          includeAbsolute: false,
        },
      },
    }),
    eslintPlugin({ exclude: ['**/node_modules/**', '**/vendor/**'] }),
    i18n(),
  ],
  resolve: {
    alias: {
      ziggy: 'vendor/tightenco/ziggy/dist/vue.m',
    },
  },
});
xiki808 commented 1 year ago

Actually similar warning/error message is shown on Chrome too, I didn't notice at first as it shows up under verbose message group

image

xiCO2k commented 1 year ago

Thanks for the feedback, will check that up ASAP

xiCO2k commented 1 year ago

Hey @xiki808 I was not able to replicate that case unfortunatelly :(

Tchilly commented 1 year ago

I'm getting the same error in edge (Chrome);

Uncaught (in promise) TypeError: langs[lang] is not a function at resolve (app.js:formatted:43:62) at avoidException (avoid-exceptions.js:3:16) at I18n.resolveLangAsync (index.js:185:20) at index.js:159:18 at new Promise (<anonymous>) at I18n.loadLanguageAsync (index.js:155:16) at I18n.load (index.js:129:42) at new I18n (index.js:113:14) at I18n.getSharedInstance (index.js:309:84) at Object.install (index.js:83:44)

my app.js;

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, app, props, plugin }) {
        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .use(ZiggyVue, Ziggy)
            .use(i18nVue, {
                resolve: async lang => {
                    const langs = import.meta.glob('../../lang/*.json');
                    return await langs[`../../lang/${lang}.json`]();
                }
            })
            .mount(el);
    },
});

Screenshot 2022-12-16 023238

Update: Also getting this in Chrome; Screenshot 2022-12-16 023500

Tchilly commented 1 year ago

Got rid of the error with;

if (typeof langs[`../../lang/${lang}.json`] != "undefined") {
    return await langs[`../../lang/${lang}.json`]();
}

Looks like one of the objects in langs are undefined. When logging lang, it contains both en & php_en, but for some reason one of them don't resolve in langs, even if it looks like they do.

xiCO2k commented 1 year ago

Thanks @Tchilly

xiki808 commented 1 year ago

Sorry for the late reply, I fixed this by adding the php_ prefix:

resolve: lang => import(../../lang/php_${lang}.json),

haztakki commented 1 year ago

I know this has been closed but I wanted to update it further. I can confirm that I also have this issue. @xiki808's solution seems to resolve the error, but I'm curious as to why @xiCO2k isn't able to reproduce it. I have translations for both English and Finnish in my project. The Finnish translations contain äö characters, but I don't think that's the issue. I have a feeling that it's down to the naming conventions. @xiCO2k Are you able to reproduce this if you create a nested folder structure?

/lang/en/pages/home.php
{{ $t('pages.home.welcome') }}
{{ $t('pages/home.welcome') }}

This is a stab in the dark, but I thought I would try my luck.

Jacobtims commented 1 year ago

I only get the error when there is no .json translation file.

Abhishek0116 commented 1 month ago

I solved it something like this:

in app.js file

            .use(i18nVue, {
                resolve: async (lang) => {
                    try {
                        const langs = import.meta.glob("../../lang/*.json");
                        let currentLang = lang.includes("php_")
                            ? lang.toString()
                            : `php_${lang.toString()}`;
                        return await langs[`../../lang/${currentLang}.json`]();
                    } catch (e) {
                        console.error(e);
                    }
                },
            }) 

and in ssr.js file (if you are using ssr)

                .use(i18nVue, {
                    resolve: (lang) => {
                        try {
                            const langs = import.meta.glob(
                                "../../lang/*.json",
                                {
                                    eager: true,
                                },
                            );
                            let currentLang = lang.includes("php_")
                                ? lang.toString()
                                : `php_${lang.toString()}`;
                            return langs[`../../lang/${currentLang}.json`].default;
                        } catch (e) {
                            console.log(e);
                        }
                    },
                })