nuxt.jsstrapinuxt3.jsnuxt-i18nnuxt-strapi

Set fetched data as options on nuxt.config


I'm working with nuxt 3, is there any way in which I can automatically set options for a module?

I want to fetch the active locales and the default locale I set up in Strapi, and automatically set those in the i18n module.

export default defineNuxtConfig({
  modules: [
    '@nuxtjs/i18n',
    '@nuxtjs/strapi'
  ],
  i18n: {
    strategy: 'prefix_except_default',
    locales: [ // locales would be fetched from Strapi endpoint
      {
        code: 'en',
        file: 'en.json'
      },
      {
        code: 'it',
        file: 'it.json'
      },
    ],
    langDir: 'assets/i18n',
    defaultLocale: 'en', // default locale would be fetched from Strapi endpoint
  },
})

I tried to import them with a plugin, but I can't sort it out, I guess there are better methods to do what I need to do


Solution

  • You can combine i18n plugin with pinia store.

    stores/index.js

    import { defineStore } from "pinia";
    import { useFetch } from "#app";
        
    const fetchDataByLocale = async (locale, headers) => {
        const res = await useFetch('http://<STRAPI_URL>/api/posts', {
            headers,
            params: {
                locale
            }
        });
    
        if (res.error.value) {
            throw createError({
                statusCode: res.error.value.statusCode,
                statusMessage: res.error.value.statusMessage
            });
        }
    
        return res.data;
    };
    
    export const useStore = defineStore("store", {
        state: () => ({
            data: {
                en: [],
                it: []
            }
        }),
        actions: {
            async fetchData() {
                const token = "<STRAPI_TOKEN>";
                const headers = {
                    Authorization: `Bearer ${token}`
                };
    
                this.data.en = await fetchDataByLocale('en', headers);
                this.data.it = await fetchDataByLocale('it', headers);
    
            }
        },
        getters: {
            getData(state) {
                return state.data;
            }
        }
    });
    

    plugins/i18n.ts

    import { createI18n } from 'vue-i18n'
    import { useStore } from '~/stores/index.js'
    import { storeToRefs } from 'pinia';
    
    export default defineNuxtPlugin(async ({ vueApp }) => {
        const store = await useStore();
        await store.fetchData();
        const locales = storeToRefs(store.getData);
        const defaultLocale = "en"
        const i18nInstance = createI18n({
            legacy: false,
            globalInjection: true,
            locale: defaultLocale,
            locales: locales
        });
        vueApp.use(i18nInstance);
    });
    

    sampleComponent.vue:

    <template>
        <div>
            <button @click="changeLocale('en')">English</button>
            <button @click="changeLocale('it')">Italian</button>
            <pre>{{ currentData }}</pre>
        </div>
    </template>
    
    <script>
    import { useStore } from '~/stores/index.js';
    export default {
        setup() {
            const store = useStore();
            const currentLocale = ref('en');
            store.fetchData();
            const changeLocale = (locale) => {
                currentLocale.value = locale;
            };
            const currentData = computed(() => store.data[currentLocale.value]);
            return {
                currentData,
                changeLocale
            };
        }
    };
    </script>