Set dynamic document title using route metadata and i18n, and add convenience slot binding in PaginationDisplayGeneralSearchReload.vue.

This commit is contained in:
Jeppe Bundgaard
2026-03-09 10:40:44 +01:00
parent 8c3bd310a1
commit 70038d5a4f
2 changed files with 53 additions and 1 deletions
+52 -1
View File
@@ -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">