diff --git a/frontend/components/global/LanguageDialog.vue b/frontend/components/global/LanguageDialog.vue
new file mode 100644
index 000000000000..70798410631f
--- /dev/null
+++ b/frontend/components/global/LanguageDialog.vue
@@ -0,0 +1,194 @@
+
+
+
+ {{ $t('language-dialog.select-description') }}
+
+
+
+ {{ $t("language-dialog.read-the-docs") }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/lang/messages/en-US.json b/frontend/lang/messages/en-US.json
index 33e43a867837..aeddde68e905 100644
--- a/frontend/lang/messages/en-US.json
+++ b/frontend/lang/messages/en-US.json
@@ -415,7 +415,8 @@
"search": "Search",
"site-settings": "Site Settings",
"tags": "Tags",
- "toolbox": "Toolbox"
+ "toolbox": "Toolbox",
+ "language": "Language"
},
"signup": {
"error-signing-up": "Error Signing Up",
@@ -494,5 +495,11 @@
"webhooks-enabled": "Webhooks Enabled",
"you-are-not-allowed-to-create-a-user": "You are not allowed to create a user",
"you-are-not-allowed-to-delete-this-user": "You are not allowed to delete this user"
+ },
+ "language-dialog": {
+ "choose-language": "Choose language",
+ "select-description": "Choose the language for the Mealie UI. The setting only applies to you, not other users.",
+ "how-to-contribute-description": "Is something not translated yet, mistranslated, or your language missing from the list? {read-the-docs-link} on how to contribute!",
+ "read-the-docs": "Read the docs"
}
-}
\ No newline at end of file
+}
diff --git a/frontend/layouts/default.vue b/frontend/layouts/default.vue
index 23ff5bbafb74..0d76ccab8e6b 100644
--- a/frontend/layouts/default.vue
+++ b/frontend/layouts/default.vue
@@ -36,6 +36,15 @@
+
+
+ {{ $globals.icons.translate }}
+
+
+ {{ $t('sidebar.language') }}
+
+
+
@@ -64,12 +73,13 @@
import { computed, defineComponent, onMounted, ref, useContext } from "@nuxtjs/composition-api";
import AppHeader from "@/components/Layout/AppHeader.vue";
import AppSidebar from "@/components/Layout/AppSidebar.vue";
+import LanguageDialog from "~/components/global/LanguageDialog.vue";
import TheSnackbar from "@/components/Layout/TheSnackbar.vue";
import { useCookbooks } from "~/composables/use-group-cookbooks";
import { useToggleDarkMode } from "~/composables/use-utils";
export default defineComponent({
- components: { AppHeader, AppSidebar, TheSnackbar },
+ components: { AppHeader, AppSidebar, LanguageDialog, TheSnackbar },
middleware: "auth",
setup() {
const { cookbooks } = useCookbooks();
@@ -79,6 +89,8 @@ export default defineComponent({
const toggleDark = useToggleDarkMode();
+ const languageDialog = ref(false);
+
const sidebar = ref(null);
onMounted(() => {
@@ -95,7 +107,7 @@ export default defineComponent({
};
});
});
- return { cookbookLinks, isAdmin, toggleDark, sidebar };
+ return { cookbookLinks, isAdmin, languageDialog, toggleDark, sidebar };
},
data() {
return {
diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js
index 91ec9c91c4fc..8be8864e025b 100644
--- a/frontend/nuxt.config.js
+++ b/frontend/nuxt.config.js
@@ -170,7 +170,12 @@ export default {
// END: MESSAGE_LOCALES
],
lazy: true,
+ strategy: "no_prefix",
langDir: "lang/messages",
+ detectBrowserLanguage: {
+ useCookie: true,
+ alwaysRedirect: true,
+ },
defaultLocale: "en-US",
vueI18n: {
dateTimeFormats: {
@@ -208,8 +213,8 @@ export default {
"vi-VN": require("./lang/dateTimeFormats/vi-VN.json"),
// END: DATE_LOCALES
},
+ fallbackLocale: "en-US",
},
- fallbackLocale: "es",
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
diff --git a/frontend/types/components.d.ts b/frontend/types/components.d.ts
index ed87cdc2d567..43887f9db4a0 100644
--- a/frontend/types/components.d.ts
+++ b/frontend/types/components.d.ts
@@ -15,6 +15,7 @@
import DevDumpJson from "@/components/global/DevDumpJson.vue";
import InputQuantity from "@/components/global/InputQuantity.vue";
import ToggleState from "@/components/global/ToggleState.vue";
+ import LanguageDialog from "~/components/global/LanguageDialog.vue";
import AppButtonCopy from "@/components/global/AppButtonCopy.vue";
import CrudTable from "@/components/global/CrudTable.vue";
import InputColor from "@/components/global/InputColor.vue";
@@ -49,6 +50,7 @@ declare module "vue" {
DevDumpJson: typeof DevDumpJson;
InputQuantity: typeof InputQuantity;
ToggleState: typeof ToggleState;
+ LanguageDialog: typeof LanguageDialog;
AppButtonCopy: typeof AppButtonCopy;
CrudTable: typeof CrudTable;
InputColor: typeof InputColor;