How to get elements to be Reactive in this particular case (Vue3, Pinia)?

Hi everyone and first of all thanks anyone who will try to help.

I have this code here which is used for the menu in the vue (it is vue component):

<script lang="ts" setup>
import { computed, ref, onMounted, watch, onBeforeUnmount } from "vue";
import { useRoute, useRouter } from "vue-router";
import { logoDark, logoLight, logoSm } from "@/assets/images/utils";
import { getMenuItems } from "@/app/layout/utils";
import SubMenu from "@/app/layout/menu/SubMenu.vue";
import { useLayoutStore } from "@/store/layout";
import { LucideNetwork } from "lucide-vue-next";
import { LAYOUTS, SIDEBAR_SIZE } from "@/app/const";
import { v4 as uuidv4 } from "uuid";
import { MenuItemType, SubMenuType } from "@/app/layout/types";
import { useAppStore } from '@/store/index';

const layoutStore = computed(() => useLayoutStore());
const layoutType = computed(() => layoutStore.value.layoutType);
const isHorizontal = computed(() => layoutType.value === LAYOUTS.HORIZONTAL);

const route = useRoute();
const router = useRouter();
const path = computed(() => route.path);

const LanguageStore = useAppStore();
const t = computed(() => LanguageStore.translations);

// Define menuItems as a ref and update it whenever the language changes
const menuItems = ref<MenuItemType[]>([]);
menuItems.value = getMenuItems(t);

const sideBarComponent = computed(() => {
  const sideBarSize = layoutStore.value.sideBarSize;

  if (sideBarSize === SIDEBAR_SIZE.SMALL) {
    return "div";
  } else {
    return "simplebar";
  }
});
const onLogoClick = () => {
  router.push("/");
};
const mappedData: any = menuItems.value.map((item) => {
  if (item.subMenu) {
    const nestedSubMenu = item.subMenu.map((subMenu: SubMenuType) => {
      if (subMenu.subMenu) {
        return {
          ...subMenu,
          isActive: false,
          id: uuidv4()
        };
      }
      return {
        ...subMenu
      };
    });

    return {
      ...item,
      subMenu: nestedSubMenu,
      isActive: false,
      id: uuidv4()
    };
  }
  return {
    ...item,
    id: uuidv4()
  };
});

const clientWidth = ref(document.documentElement.clientWidth);

const menuItemData = ref<MenuItemType[]>(mappedData);

const onWindowResize = () => {
  clientWidth.value = document.documentElement.clientWidth;
  if (isHorizontal.value) {
    setTimeout(() => {
      setupHorizontalMenu();
    }, 300);
  } else {
    menuItemData.value = mappedData;
  }
};

onMounted(() => {
  window.addEventListener("resize", onWindowResize);

  if (isHorizontal.value) {
    setTimeout(() => {
      setupHorizontalMenu();
    }, 300);
  }
  document.documentElement.addEventListener("click", (event: any) => {
    isSubMenu(event.target);
  });
});

onBeforeUnmount(() => {
  document.documentElement.removeEventListener("click", (event: any) => {
    isSubMenu(event.target);
  });
  window.removeEventListener("resize", setupHorizontalMenu);
  window.removeEventListener("resize", onWindowResize);
});

const isSubMenu = (element: HTMLElement | null): boolean => {
  if (!element) {
    hideActivation();
    return false;
  }
  return (
    element.classList.contains("submenu-dropdown") ||
    element.classList.contains("app-menu") ||
    isSubMenu(element.parentElement)
  );
};

watch(layoutType, (newVal: string) => {
  if (newVal === LAYOUTS.HORIZONTAL) {
    setupHorizontalMenu();
  } else {
    menuItemData.value = mappedData;
  }
});

const setupHorizontalMenu = () => {
  if (clientWidth.value >= 768) {
    window.addEventListener("resize", setupHorizontalMenu);

    let isMoreMenu = false;
    const navData = mappedData.filter(
      (menuItem: MenuItemType) => !menuItem.isHeader
    );
    const horizontalMenuEle = document.querySelector(".app-menu");
    const navbarNav = document.querySelector(".navbar-header");
    if (navbarNav) {
      const fullMenuWidth = navbarNav.clientWidth - 100 || 0;

      let totalItemsWidth = 0;
      let visibleItems: MenuItemType[] = [];
      let hiddenItems: MenuItemType[] = []; // Add type annotation here

      for (let i = 0; i < navData.length; i++) {
        const element: HTMLElement = horizontalMenuEle?.querySelector(
          "#navbar-nav"
        )?.children[i] as HTMLElement;
        const itemWidth = element?.offsetWidth || 0;
        totalItemsWidth += itemWidth;

        if (totalItemsWidth + 250 <= fullMenuWidth) {
          visibleItems.push(navData[i]);
        } else {
          hiddenItems.push(navData[i]);
        }
      }

      const moreMenuItem = {
        title: "more",
        icon: LucideNetwork,
        isActive: false,
        subMenu: hiddenItems,
        id: uuidv4(),
        stateVariables: isMoreMenu,
        click: (e: any) => {
          e.preventDefault();
          isMoreMenu = !isMoreMenu;
        }
      };

      let updatedMenuItems: any = [...visibleItems];
      if (hiddenItems.length) {
        updatedMenuItems.push(moreMenuItem);
      }

      menuItemData.value = updatedMenuItems;
    }
    setTimeout(() => {
      handleDropdownMenu();
    }, 500);
  } else {
    menuItemData.value = mappedData;
  }
};



const toggleActivation = (menuItemId: string) => {
  let hasSubMenu = false; // Flag to track if the element has submenu items

  menuItemData.value = menuItemData.value.map((item: MenuItemType) => {
    if (item.id === menuItemId) {
      return {
        ...item,
        isActive: !item.isActive
      };
    } else if (item.subMenu) {
      const nestedSubmenu = getActivations(menuItemId, item);
      const firstLevelMenu = {
        ...item,
        isActive: nestedSubmenu.some(
          (subMenu: SubMenuType) => subMenu.isActive
        ),
        subMenu: nestedSubmenu
      };

      // Update flag if submenu exists
      if (!hasSubMenu && nestedSubmenu.length > 0) {
        hasSubMenu = true;
      }

      return firstLevelMenu;
    }
    return { ...item, isActive: false };
  });

  // Call closeSidebar() only if the element doesn't have submenu items
  if (!hasSubMenu) {
    closeSidebar();
  }
};



const closeSidebar = () => {
  const backdropOverlay = document.querySelector(".backdrop-overlay");
  if (backdropOverlay instanceof HTMLElement) {
    backdropOverlay.click();
  }
};

const getActivations: any = (menuItemId: string, menuItem: MenuItemType) => {
  const preparedData = menuItem.subMenu?.map((subMenu: SubMenuType) => {
    if (menuItemId && subMenu.id === menuItemId) {
      return {
        ...subMenu,
        isActive: !subMenu.isActive
      };
    } else {
      if (subMenu.subMenu) {
        const nestedSubmenu = getActivations(menuItemId, subMenu);

        const temp = {
          ...subMenu,
          subMenu: nestedSubmenu,
          isActive: nestedSubmenu.some((item: SubMenuType) => item.isActive)
        };
        return temp;
      }
      return { ...subMenu, isActive: false };
    }
  });

  return preparedData;
};

const hideActivation = () => {
  menuItemData.value = menuItemData.value.map((item) => {
    if (item.subMenu) {
      const nestedSubmenu = item.subMenu.map((subMenu) => {
        return {
          ...subMenu,
          isActive: false
        };
      });
      return {
        ...item,
        isActive: false,
        subMenu: nestedSubmenu
      };
    }
    return { ...item, isActive: false };
  });
};

function handleDropdownMenu() {
  const dropdownToggleButtons = document
    .querySelector(".app-menu")
    ?.querySelectorAll(".dropdown-button");
  dropdownToggleButtons?.forEach((button) => {
    const content = button.nextElementSibling;
    button.addEventListener("click", () => {
      if (!content) {
        return;
      }
      setTimeout(() => {
        // get the dropdown menu element
        var dropdownMenu = button;
        const subMenus: any = dropdownMenu.nextElementSibling
          ? dropdownMenu.nextElementSibling
          : dropdownMenu.parentElement?.nextElementSibling;
        if (subMenus) {
          const isLeftFull = subMenus.classList.contains(
            "group-data-[layout=horizontal]:ltr:md:left-full"
          );

          const isRightFull = subMenus.classList.contains(
            "group-data-[layout=horizontal]:rtl:md:right-full"
          );
          if (isLeftFull || isRightFull) {
            if (dropdownMenu && subMenus) {
              // get the position and dimensions of the dropdown menu
              var dropdownOffset = subMenus.getBoundingClientRect();
              var dropdownWidth = subMenus.offsetWidth;
              var dropdownHeight = subMenus.offsetHeight;

              // get the dimensions of the screen
              var screenWidth = window.innerWidth;
              var screenHeight = window.innerHeight;

              // calculate the maximum x and y coordinates of the dropdown menu
              var maxDropdownX = dropdownOffset.left + dropdownWidth;
              var maxDropdownY = dropdownOffset.top + dropdownHeight;

              // check if the dropdown menu goes outside the screen
              var isDropdownOffScreen =
                maxDropdownX > screenWidth || maxDropdownY > screenHeight;
              if (isDropdownOffScreen) {
                if (isLeftFull) {
                  subMenus.classList.remove(
                    "group-data-[layout=horizontal]:ltr:md:left-full"
                  );
                  subMenus.classList.add(
                    "group-data-[layout=horizontal]:ltr:md:right-full"
                  );
                }
              } else if (isRightFull) {
                subMenus.classList.add(
                  "group-data-[layout=horizontal]:rtl:md:left-full"
                );
                subMenus.classList.remove(
                  "group-data-[layout=horizontal]:rtl:md:right-full"
                );
              }
            }
          }
        }
      }, 10);
    });
  });
}
</script>
<template>
  <div
    class="app-menu w-vertical-menu bg-vertical-menu ltr:border-r rtl:border-l border-vertical-menu-border fixed bottom-0 top-0 z-drawer md:z-[1003] transition-all duration-75 ease-linear group-data-[sidebar-size=md]:w-vertical-menu-md group-data-[sidebar-size=sm]:w-vertical-menu-sm group-data-[sidebar-size=sm]:pt-header group-data-[sidebar=dark]:bg-vertical-menu-dark group-data-[sidebar=dark]:border-vertical-menu-dark group-data-[sidebar=brand]:bg-vertical-menu-brand group-data-[sidebar=brand]:border-vertical-menu-brand group-data-[sidebar=modern]:bg-gradient-to-tr group-data-[sidebar=modern]:to-vertical-menu-to-modern group-data-[sidebar=modern]:from-vertical-menu-form-modern group-data-[layout=horizontal]:w-full group-data-[layout=horizontal]:bottom-auto group-data-[layout=horizontal]:top-header hidden md:block print:hidden group-data-[sidebar-size=sm]:absolute group-data-[sidebar=modern]:border-vertical-menu-border-modern group-data-[layout=horizontal]:dark:bg-zink-700 group-data-[layout=horizontal]:border-t group-data-[layout=horizontal]:dark:border-zink-500 group-data-[layout=horizontal]:border-r-0 group-data-[sidebar=dark]:dark:bg-zink-700 group-data-[sidebar=dark]:dark:border-zink-600 group-data-[layout=horizontal]:group-data-[navbar=scroll]:absolute group-data-[layout=horizontal]:group-data-[navbar=bordered]:top-[calc(theme('spacing.header')_+_theme('spacing.4'))] group-data-[layout=horizontal]:group-data-[navbar=bordered]:inset-x-4 group-data-[layout=horizontal]:group-data-[navbar=hidden]:top-0 group-data-[layout=horizontal]:group-data-[navbar=hidden]:h-16 group-data-[layout=horizontal]:group-data-[navbar=bordered]:w-[calc(100%_-_2rem)] group-data-[layout=horizontal]:group-data-[navbar=bordered]:[&.sticky]:top-header group-data-[layout=horizontal]:group-data-[navbar=bordered]:rounded-b-md group-data-[layout=horizontal]:shadow-md group-data-[layout=horizontal]:shadow-slate-500/10 group-data-[layout=horizontal]:dark:shadow-zink-500/10 [layout=horizontal]:ltr:pl-0 [layout=horizontal]:rtl:pr-0 md:group-data-[layout=horizontal]:z-10"
  >
    <div
      class="flex items-center justify-center px-5 text-center h-header group-data-[layout=horizontal]:hidden group-data-[sidebar-size=sm]:fixed group-data-[sidebar-size=sm]:top-0 group-data-[sidebar-size=sm]:bg-vertical-menu group-data-[sidebar-size=sm]:group-data-[sidebar=dark]:bg-vertical-menu-dark group-data-[sidebar-size=sm]:group-data-[sidebar=brand]:bg-vertical-menu-brand group-data-[sidebar-size=sm]:group-data-[sidebar=modern]:bg-gradient-to-br group-data-[sidebar-size=sm]:group-data-[sidebar=modern]:to-vertical-menu-to-modern group-data-[sidebar-size=sm]:group-data-[sidebar=modern]:from-vertical-menu-form-modern group-data-[sidebar-size=sm]:group-data-[sidebar=modern]:bg-vertical-menu-modern group-data-[sidebar-size=sm]:z-10 group-data-[sidebar-size=sm]:w-[calc(theme('spacing.vertical-menu-sm')_-_1px)] group-data-[sidebar-size=sm]:group-data-[sidebar=dark]:dark:bg-zink-700"
    >
      <div
        @click="onLogoClick"
        class="group-data-[sidebar=dark]:hidden group-data-[sidebar=brand]:hidden group-data-[sidebar=modern]:hidden cursor-pointer"
      >
        <span class="hidden group-data-[sidebar-size=sm]:block">
          <img :src="logoSm" alt="" class="h-10 mx-auto" />
        </span>
        <span class="group-data-[sidebar-size=sm]:hidden">
          <img :src="logoDark" alt="" class="h-14 mx-auto" />
        </span>
      </div>
      <div
        @click="onLogoClick"
        class="hidden group-data-[sidebar=dark]:block group-data-[sidebar=brand]:block group-data-[sidebar=modern]:block cursor-pointer"
      >
        <span class="hidden group-data-[sidebar-size=sm]:block">
          <img :src="logoSm" alt="" class="h-6 mx-auto" />
        </span>
        <span class="group-data-[sidebar-size=sm]:hidden">
          <img :src="logoLight" alt="" class="h-14 mx-auto" />
        </span>
      </div>
      <button type="button" class="hidden p-0 float-end" id="vertical-hover">
        <i class="ri-record-circle-line"></i>
      </button>
    </div>
    <component
      :is="sideBarComponent"
      id="menu-scrollbar"
      class="group-data-[sidebar-size=md]:max-h-[calc(100vh_-_theme('spacing.header')_*_1.2)] group-data-[sidebar-size=lg]:max-h-[calc(100vh_-_theme('spacing.header')_*_1.2)] group-data-[layout=horizontal]:h-56 group-data-[layout=horizontal]:md:h-auto group-data-[layout=horizontal]:overflow-auto group-data-[layout=horizontal]:md:overflow-visible group-data-[layout=horizontal]:max-w-screen-2xl group-data-[layout=horizontal]:mx-auto"
    >
      <div>
        <ul
          class="group-data-[layout=horizontal]:flex group-data-[layout=horizontal]:flex-col group-data-[layout=horizontal]:md:flex-row"
          id="navbar-nav"
        >
          <template v-for="menuItem in menuItemData" :key="menuItem.title">
            <li
              v-if="menuItem.isHeader"
              class="px-4 py-1 text-vertical-menu-item group-data-[sidebar=dark]:text-vertical-menu-item-dark group-data-[sidebar=brand]:text-vertical-menu-item-brand group-data-[sidebar=modern]:text-vertical-menu-item-modern uppercase font-medium text-[11px] cursor-default tracking-wider group-data-[sidebar-size=sm]:hidden group-data-[layout=horizontal]:hidden inline-block group-data-[sidebar-size=md]:block group-data-[sidebar-size=md]:underline group-data-[sidebar-size=md]:text-center group-data-[sidebar=dark]:dark:text-zink-200"
            >
              <span :data-key="`t-${menuItem.title}`">
                <!-- {!! $t(`t-${menuItem.title}`) !!} -->
                {{ menuItem.title }}
              </span>
            </li>
            <template v-else-if="menuItem.subMenu">
              <SubMenu
                :menuItem="menuItem"
                @toggleActivation="toggleActivation"
              />
            </template>
            <li
              v-else-if="!menuItem.subMenu && menuItem.path"
              class="relative group-data-[layout=horizontal]:shrink-0 group/sm"
            >
              <router-link
                class="relative flex items-center ltr:pl-3 rtl:pr-3 ltr:pr-5 rtl:pl-5 mx-3 my-1 group/menu-link text-vertical-menu-item-font-size font-normal transition-all duration-75 ease-linear rounded-md py-2.5 text-vertical-menu-item hover:text-vertical-menu-item-hover hover:bg-vertical-menu-item-bg-hover [&.active]:text-vertical-menu-item-active [&.active]:bg-vertical-menu-item-bg-active group-data-[sidebar=dark]:text-vertical-menu-item-dark group-data-[sidebar=dark]:hover:text-vertical-menu-item-hover-dark group-data-[sidebar=dark]:dark:hover:text-custom-500 group-data-[layout=horizontal]:dark:hover:text-custom-500 group-data-[sidebar=dark]:hover:bg-vertical-menu-item-bg-hover-dark group-data-[sidebar=dark]:dark:hover:bg-zink-600 group-data-[sidebar=dark]:[&.active]:text-vertical-menu-item-active-dark group-data-[sidebar=dark]:[&.active]:bg-vertical-menu-item-bg-active-dark group-data-[sidebar=brand]:text-vertical-menu-item-brand group-data-[sidebar=brand]:hover:text-vertical-menu-item-hover-brand group-data-[sidebar=brand]:hover:bg-vertical-menu-item-bg-hover-brand group-data-[sidebar=brand]:[&.active]:bg-vertical-menu-item-bg-active-brand group-data-[sidebar=brand]:[&.active]:text-vertical-menu-item-active-brand group-data-[sidebar=modern]:text-vertical-menu-item-modern group-data-[sidebar=modern]:hover:bg-vertical-menu-item-bg-hover-modern group-data-[sidebar=modern]:hover:text-vertical-menu-item-hover-modern group-data-[sidebar=modern]:[&.active]:bg-vertical-menu-item-bg-active-modern group-data-[sidebar=modern]:[&.active]:text-vertical-menu-item-active-modern group-data-[sidebar-size=md]:block group-data-[sidebar-size=md]:text-center group-data-[sidebar-size=sm]:group-hover/sm:w-[calc(theme('spacing.vertical-menu-sm')_*_3.63)] group-data-[sidebar-size=sm]:group-hover/sm:bg-vertical-menu group-data-[sidebar-size=sm]:group-data-[sidebar=dark]:group-hover/sm:bg-vertical-menu-dark group-data-[sidebar-size=sm]:group-data-[sidebar=modern]:group-hover/sm:bg-vertical-menu-border-modern group-data-[sidebar-size=sm]:group-data-[sidebar=brand]:group-hover/sm:bg-vertical-menu-brand group-data-[sidebar-size=sm]:my-0 group-data-[layout=horizontal]:m-0 group-data-[layout=horizontal]:ltr:pr-8 group-data-[layout=horizontal]:rtl:pl-8 group-data-[layout=horizontal]:hover:bg-transparent group-data-[layout=horizontal]:[&.active]:bg-transparent [&.dropdown-button]:before:absolute [&.dropdown-button]:[&.show]:before:content-['ea4e'] [&.dropdown-button]:before:content-['ea6e'] [&.dropdown-button]:before:font-remix ltr:[&.dropdown-button]:before:right-2 rtl:[&.dropdown-button]:before:left-2 [&.dropdown-button]:before:text-16 group-data-[sidebar-size=sm]:[&.dropdown-button]:before:hidden group-data-[sidebar-size=md]:[&.dropdown-button]:before:hidden group-data-[sidebar=dark]:dark:text-zink-200 group-data-[layout=horizontal]:dark:text-zink-200 group-data-[sidebar=dark]:[&.active]:dark:bg-zink-600 group-data-[layout=horizontal]:dark:[&.active]:text-custom-500 rtl:[&.dropdown-button]:before:rotate-180 group-data-[layout=horizontal]:[&.dropdown-button]:before:rotate-90 group-data-[layout=horizontal]:[&.dropdown-button]:[&.show]:before:rotate-0 rtl:[&.dropdown-button]:[&.show]:before:rotate-0"
                :class="{
                  active: path === menuItem.path
                }"
                :to="menuItem.path"
                @click="toggleActivation"
              >
                <span
                  class="min-w-[1.75rem] group-data-[sidebar-size=sm]:h-[1.75rem] inline-block text-start text-[16px] group-data-[sidebar-size=md]:block"
                >
                  <component
                    :is="menuItem.icon"
                    class="h-4 group-data-[sidebar-size=sm]:h-5 group-data-[sidebar-size=sm]:w-5 transition group-hover/menu-link:animate-icons fill-slate-100 group-hover/menu-link:fill-blue-200 group-data-[sidebar=dark]:fill-vertical-menu-item-bg-active-dark group-data-[sidebar=dark]:dark:fill-zink-600 group-data-[layout=horizontal]:dark:fill-zink-600 group-data-[sidebar=brand]:fill-vertical-menu-item-bg-active-brand group-data-[sidebar=modern]:fill-vertical-menu-item-bg-active-modern group-data-[sidebar=dark]:group-hover/menu-link:fill-vertical-menu-item-bg-active-dark group-data-[sidebar=dark]:group-hover/menu-link:dark:fill-custom-500/20 group-data-[layout=horizontal]:dark:group-hover/menu-link:fill-custom-500/20 group-data-[sidebar=brand]:group-hover/menu-link:fill-vertical-menu-item-bg-active-brand group-data-[sidebar=modern]:group-hover/menu-link:fill-vertical-menu-item-bg-active-modern group-data-[sidebar-size=md]:block group-data-[sidebar-size=md]:mx-auto group-data-[sidebar-size=md]:mb-2"
                  />
                </span>
                <span
                  class="group-data-[sidebar-size=sm]:ltr:pl-10 group-data-[sidebar-size=sm]:rtl:pr-10 align-middle group-data-[sidebar-size=sm]:group-hover/sm:block group-data-[sidebar-size=sm]:hidden"
                  :data-key="`t-${menuItem.title}`"
                >
                  <!--{{ $t(`t-${menuItem.title}`) }}-->
                  {{ menuItem.title }}
                </span>
              </router-link>
            </li>
          </template>
        </ul>
      </div>
    </component>
  </div>
</template>

This code calls the function getMenuItems which is another file and looks like this:

import {
  MonitorDot,
  BuildingIcon,
  TableIcon,
  Users2,
  UserIcon,
  CalendarIcon,
  CreditCardIcon,
  LogOutIcon,
  SettingsIcon,
  UserCogIcon
} from "lucide-vue-next";
import { MenuItemType } from "@/app/layout/types";

export function getMenuItems(t): MenuItemType[] {
  return [
    { isHeader: true, title: "Menu" },
    {
      icon: MonitorDot,
      title: t.value?.general?.home,
      path: "/"
    },
    {
      icon: BuildingIcon,
      title: t.value?.general?.organisations,
      path: "/organisations"
    },
    {
      icon: BuildingIcon,
      title: t.value?.general?.buildings,
      path: "/buildings"
    },
    {
      icon: TableIcon,
      title: t.value?.general?.classrooms,
      path: "/classrooms"
    },
    {
      icon: Users2,
      title: t.value?.general?.classes,
      path: "/classes"
    },
    {
      icon: UserIcon,
      title: t.value?.general?.teachers,
      path: "/teachers"
    },
    {
      icon: Users2,
      title: t.value?.general?.students,
      path: "/students"
    },
    {
      icon: Users2,
      title: "Administration",
      path: "/administration"
    },
    {
      icon: UserIcon,
      title: t.value?.general?.subjects,
      path: "/subjects"
    },
    {
      icon: CalendarIcon,
      title: t.value?.general?.calendars,
      path: "/calendar"
    },
    {
      icon: CreditCardIcon,
      title: "Payments",
      path: "/payments"
    },
    { isHeader: true, title: "settings" },
    {
      icon: UserCogIcon,
      title: t.value?.general?.profile,
      path: "/profile"
    },
    {
      icon: Users2,
      title: t.value?.general?.teams,
      path: "/teams"
    },
    {
      icon: Users2,
      title: t.value?.general?.users,
      path: "/users"
    },
    {
      icon: SettingsIcon,
      title: "Settings",
      path: "/settings"
    },
    {
      icon: LogOutIcon,
      title: t.value?.general?.logout,
      path: "/logout"
    },
  ];
}

I have an issue where my translations are not reactive.
Even when I put watch on t variable the elements on the screen are not changed but I can see that t changes in console.log every time without any issues.

Can somebody help?

I have tried using watch property from vue like this but that didn’t help:

watch(t, (newValue) => {
  menuItems.value = getMenuItems(newValue);

  console.log(menuItems.value);
});

If I console.log t variable, I get that is changed but menuItems.value get some undefined values, but I have the translations inside (they are stored in localStorage).

You can also check my store for language:

import { defineStore } from 'pinia';
import { createPinia } from "pinia";
import { updateTranslations } from '@/assets/lang';

export interface Translation {
  [key: string]: string;
}

interface AppState {
  locale: string;
  translations: Translation;
}

export const useAppStore = defineStore("app", {
  state: (): AppState => ({
    locale: 'en', // Default locale
    translations: {}, // Translations object
  }),
  actions: {
    async changeLanguage(locale: string) {
        try {
          const translations = await updateTranslations(locale);
          if (translations === undefined) {
            throw new Error('Translations not found');
          }
          this.locale = locale;
          this.translations = translations;

        } catch (error) {
          console.error('Error changing language:', error);
        }
    },
    async initializeApp() {
      try {
        // Check if locale is stored in local storage, if not, fallback to default locale
        const storedLocale = localStorage.getItem('locale');
        const defaultLocale = storedLocale || import.meta.env.VITE_APP_DEFAULT_LOCALE;
        
        const translations = await updateTranslations(defaultLocale);
        if (translations === undefined) {
          throw new Error('Translations not found');
        }

        this.translations = translations;
        
      } catch (error) {
        console.error('Error initializing app:', error);
        // Handle error gracefully, e.g., show a message to the user
      }
    },
    async updateTranslations(locale: string): Promise<Translation> {
        try {
          const translations = await updateTranslations(locale);
          if (translations === undefined) {
            throw new Error('Translations not found');
          }
          return translations;
        } catch (error) {
          console.error('Error updating translations:', error);
          // Handle error gracefully
          throw error;
        }
      }  
  },
});

export default createPinia();

And my code for the changing the languge (vue component):

<script lang="ts" setup>
import { usFlag } from "@/assets/images/flags/utils";
import { languagesData } from "@/app/layout/navbar/utils";
import NavBtn from "@/app/layout/navbar/Button.vue";
import { onMounted, ref } from "vue";
import { useAppStore } from '@/store/index';

defineProps({
  showName: {
    type: Boolean,
    default: false
  }
});

const LanguageStore = useAppStore();

const langTitle = ref("English");
const langFlagSrc = ref(usFlag); 

const setLanguage = async (entry: { [key: string]: string }) => {
  const { src, lang, title } = entry;
  const element = document.getElementById('header-lang-img');
  
  if (element) {
    element.setAttribute('src', src);
  }

  // Call changeLanguage function from Pinia store
  await LanguageStore.changeLanguage(lang);
  // Update langTitle with the selected language
  langTitle.value = title;
  langFlagSrc.value = src;

  // Store the selected language in local storage
  localStorage.setItem('selectedLanguage', lang);

  // Reload the page after changing the language
  window.location.reload();
};

// Set the selected language from local storage on component mount
onMounted(() => {
  const selectedLanguage = localStorage.getItem('selectedLanguage');
  if (selectedLanguage) {
    LanguageStore.changeLanguage(selectedLanguage);
    // Optionally, update langTitle and langFlagSrc with the selected language
    const languageEntry = languagesData.find(entry => entry.lang === selectedLanguage);
    if (languageEntry) {
      langTitle.value = languageEntry.title;
      langFlagSrc.value = languageEntry.src;
    }
  }
});
</script>


<template>
  <TList :items="languagesData" placement="bottom-start">
    <template #title>
      <button
        v-if="showName"
        type="button"
        class="inline-flex items-center gap-3 transition-all duration-200 ease-linear dropdown-toggle btn border-slate-200 dark:border-zink-400/60 group/items focus:border-custom-500 dark:focus:border-custom-500"
      >
        <img
          :src="langFlagSrc"
          alt="language-flag"
          id="header-lang-img"
          class="object-cover h-5 rounded-full"
        />
        <h6
          class="text-base font-medium transition-all duration-200 ease-linear text-slate-600 group-hover/items:text-custom-500 dark:text-zink-200 dark:group-hover/items:text-custom-500"
        >
          {{ langTitle }}
        </h6>
      </button>
      <NavBtn class="dropdown" v-else>
        <img
          :src="langFlagSrc"
          alt="language-flag"
          id="header-lang-img"
          class="h-5 rounded-sm"
        />
      </NavBtn>
    </template>
    <template #default="{ data }">
      <div
        class="flex items-center gap-3 group/items language"
        :data-lang="data.lang"
        :title="data.title"
        @click.prevent="setLanguage(data)"
      >
        <img :src="data.src" alt="" class="object-cover h-4 rounded-full" />
        <h6
          class="transition-all duration-200 ease-linear font-15medium text- text-slate-600 dark:text-zink-200 group-hover/items:text-custom-500"
        >
          {{ data.title }}
        </h6>
      </div>
    </template>
  </TList>
</template>

New contributor

Programmar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật