UNPKG

nuxt-google-translate

Version:

A simple Nuxt module that integrates the Google Translate widget into your Nuxt.js application, allowing seamless multilingual support without requiring an API key.

106 lines (105 loc) 3.75 kB
import { ref, readonly } from "vue"; import { defineNuxtPlugin, useRuntimeConfig } from "#app"; export default defineNuxtPlugin((nuxtApp) => { const config = useRuntimeConfig(); const options = config.public.googleTranslate; const defaultLanguage = options?.defaultLanguage ?? "en"; const supportedLanguages = options?.supportedLanguages ?? ["en"]; const activeLanguage = ref(defaultLanguage); if (import.meta.client) { const cookieLang = document.cookie.split("; ").find((row) => row.startsWith("googtrans="))?.split("=")[1]?.split("/")[2]; if (cookieLang && supportedLanguages.includes(cookieLang)) { activeLanguage.value = cookieLang; } } const isLoaded = ref(false); const deleteGoogtransCookie = () => { const cookieName = "googtrans"; const expiry = "expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; document.cookie = `${cookieName}=; ${expiry}`; document.cookie = `${cookieName}=; ${expiry} domain=${window.location.hostname};`; const baseDomain = window.location.hostname.split(".").slice(-2).join("."); if (baseDomain !== window.location.hostname) { document.cookie = `${cookieName}=; ${expiry} domain=.${baseDomain};`; } }; const setLanguage = (lang) => { if (!supportedLanguages.includes(lang)) { console.warn(`[nuxt-google-translate] Unsupported language: ${lang}.`); return; } if (lang === defaultLanguage) { deleteGoogtransCookie(); if (activeLanguage.value !== defaultLanguage) { location.reload(); } activeLanguage.value = defaultLanguage; return; } if (lang !== activeLanguage.value) { activeLanguage.value = lang; updateGoogleTranslate(lang); if (import.meta.client) { document.cookie = `googtrans=/en/${lang};path=/;`; } } }; const updateGoogleTranslate = (lang) => { if (!import.meta.client || !isLoaded.value) return; const select = document.querySelector(".goog-te-combo"); if (select) { select.value = lang; select.dispatchEvent(new Event("change")); } }; const initializeGoogleTranslate = () => { if (!window.google?.translate?.TranslateElement) return; new window.google.translate.TranslateElement( { pageLanguage: defaultLanguage, includedLanguages: supportedLanguages.join(","), layout: window.google.translate.TranslateElement.InlineLayout.VERTICAL, autoDisplay: false }, "nuxt_translate_element" ); isLoaded.value = true; updateGoogleTranslate(activeLanguage.value); }; const loadGoogleTranslate = () => { if (!import.meta.client || isLoaded.value) return; if (document.querySelector("#google-translate-script")) return; window.googleTranslateElementInit = initializeGoogleTranslate; if (window.google?.translate?.TranslateElement) { initializeGoogleTranslate(); return; } const script = document.createElement("script"); script.id = "google-translate-script"; script.src = "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"; script.async = true; script.defer = true; script.onload = () => { initializeGoogleTranslate(); }; script.onerror = () => { console.error("[nuxt-google-translate] Failed to load Google Translate script."); }; document.body.appendChild(script); }; if (import.meta.client) { nuxtApp.hook("app:mounted", () => { loadGoogleTranslate(); }); } return { provide: { googleTranslate: { activeLanguage: readonly(activeLanguage), supportedLanguages: readonly(supportedLanguages), setLanguage, isLoaded: readonly(isLoaded) } } }; });