Set dynamic document title using route metadata and i18n, and add convenience slot binding in PaginationDisplayGeneralSearchReload.vue.
This commit is contained in:
+52
-1
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { onMounted } from "vue";
|
||||
import { onMounted, watch } from "vue";
|
||||
import DefaultPageWrapper from "@/components/page/wrappers/DefaultPageWrapper.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
// Set the favicon to the /favicon.ico file
|
||||
@@ -8,8 +8,57 @@ import favicon from '@/assets/favicon.ico';
|
||||
import VersionCheck from "@/components/global/VersionCheck.vue";
|
||||
import {useRoute} from "vue-router";
|
||||
import LayoutV2 from "@/components/page/wrappers/LayoutV2.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const route = useRoute();
|
||||
const { t, te, locale } = useI18n({ useScope: "global" });
|
||||
const APP_TITLE = "Truck Wash";
|
||||
|
||||
const routeTitleI18nKeys = {
|
||||
"about-us": ["header.about_us"],
|
||||
"book-a-demo": ["about_us.solutions.operator.book_demo"],
|
||||
"customer-creation": ["header.customer_creation"],
|
||||
"login": ["header.customer_login"],
|
||||
"subuserlogin": ["header.customer_login"],
|
||||
"adminlogin": ["header.operator_login"],
|
||||
"guestHome": ["guest.home.title"],
|
||||
"PwaDownload": ["guest.pwa.title"],
|
||||
"connectivity-issue": ["connectivity.title"]
|
||||
};
|
||||
|
||||
const toReadableTitle = (value) => {
|
||||
if (!value) return "";
|
||||
return value
|
||||
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
||||
.replace(/[-_]+/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
.replace(/\b\w/g, (char) => char.toUpperCase());
|
||||
};
|
||||
|
||||
const resolveRouteTitle = () => {
|
||||
const titleKey = route.meta?.titleKey;
|
||||
if (typeof titleKey === "string" && te(titleKey)) {
|
||||
return t(titleKey);
|
||||
}
|
||||
|
||||
if (typeof route.meta?.title === "string" && route.meta.title.trim()) {
|
||||
return route.meta.title.trim();
|
||||
}
|
||||
|
||||
const routeName = typeof route.name === "string" ? route.name : "";
|
||||
const knownKeys = routeName ? (routeTitleI18nKeys[routeName] || []) : [];
|
||||
for (const key of knownKeys) {
|
||||
if (te(key)) return t(key);
|
||||
}
|
||||
|
||||
return toReadableTitle(routeName);
|
||||
};
|
||||
|
||||
const updateDocumentTitle = () => {
|
||||
const pageTitle = resolveRouteTitle();
|
||||
document.title = pageTitle ? `${pageTitle} | ${APP_TITLE}` : APP_TITLE;
|
||||
};
|
||||
|
||||
useHead({
|
||||
link: [
|
||||
@@ -21,6 +70,8 @@ onMounted(() => {
|
||||
//document.title = "My Vue App";
|
||||
SessionUser.initiateOnAppStart();
|
||||
});
|
||||
|
||||
watch([() => route.fullPath, locale], updateDocumentTitle, { immediate: true });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -21,6 +21,7 @@ import SessionUser from "@/components/session/token/SessionUser.vue";
|
||||
/>
|
||||
</div>
|
||||
<div class="column is-narrow" v-if="$slots.buttons">
|
||||
<!-- Custom buttons slot, passing loadList for convenience -->
|
||||
<slot name="buttons" :loadList="loadList"></slot>
|
||||
</div>
|
||||
<div class="column is-narrow pl-0">
|
||||
|
||||
Reference in New Issue
Block a user