dml_frontend/composables/usePageMeta.ts

107 lines
3.6 KiB
TypeScript

import { watch, computed } from 'vue'
import { useRoute } from 'vue-router'
import { useMainStore } from '@/stores/main'
import { useHead } from '@unhead/vue'
import { storeToRefs } from 'pinia'
// Importiere die Seiten-Routen
import { i18nPages } from '../i18n/i18n-pages' // relativ zu deinem Composable-Pfad anpassen!
export function usePageMeta () {
const route = useRoute()
const mainStore = useMainStore()
const { companyinfo } = storeToRefs(mainStore)
const currentPage = computed(() => mainStore.getPageByLink(route.path))
watch(
() => currentPage.value,
(page) => {
if (!page || !companyinfo.value) return
const metaTitle = page.SEO?.pageTitle ?? 'digimedialoop'
const metaDescription = page.SEO?.seoDescription ?? 'Webdesign und Webentwicklung'
const metaImage = page.SEO?.seoImage?.url ?? 'https://strapi.digimedialoop.de/uploads/DML_Logo_Info_c4011028f9.png'
// Canonical URL
const config = useRuntimeConfig()
const canonical = `${config.public.appUrl}${page.pageLink}`
// Robots Meta Tag
const robotsContent = route.path === '/danke' ? 'noindex, nofollow' : 'index, follow'
// Prüfe, ob Route Home oder References in allen Sprachen ist
const isHomePage = Object.values(i18nPages.index).includes(route.path)
const isReferencesPage = Object.values(i18nPages.references).includes(route.path)
// Basis LocalBusiness JSON-LD
const baseJsonLd = {
'@context': 'https://schema.org',
'@type': 'LocalBusiness',
name: companyinfo.value.company,
image: metaImage,
url: config.public.appUrl,
telephone: companyinfo.value.phone,
email: companyinfo.value.email,
address: {
'@type': 'PostalAddress',
streetAddress: companyinfo.value.street,
addressLocality: companyinfo.value.city,
postalCode: companyinfo.value.postalcode,
addressCountry: 'DE'
},
openingHoursSpecification: [
{
'@type': 'OpeningHoursSpecification',
dayOfWeek: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
opens: '09:00',
closes: '17:00'
}
]
}
// Falls Home oder References: ergänze das Rating (2 Bewertungen mit 5 Sternen)
let jsonLd = undefined
if (isHomePage || isReferencesPage) {
jsonLd = {
...baseJsonLd,
aggregateRating: {
'@type': 'AggregateRating',
ratingValue: '5',
reviewCount: '2'
}
}
} else if (isHomePage) {
// Nur LocalBusiness ohne Rating z.B.
jsonLd = baseJsonLd
}
useHead({
title: metaTitle,
meta: [
{ name: 'description', content: metaDescription },
{ name: 'robots', content: robotsContent },
{ property: 'og:title', content: metaTitle },
{ property: 'og:description', content: metaDescription },
{ property: 'og:image', content: metaImage },
{ property: 'og:type', content: 'website' },
{ name: 'twitter:title', content: metaTitle },
{ name: 'twitter:description', content: metaDescription },
{ name: 'twitter:image', content: metaImage }
],
link: [
{ rel: 'canonical', href: canonical }
],
script: jsonLd
? [
{
type: 'application/ld+json',
children: JSON.stringify(jsonLd)
}
]
: []
})
},
{ immediate: true }
)
}