changes last
This commit is contained in:
parent
85d25bef0b
commit
4e47d5d19a
@ -55,10 +55,9 @@ const breadcrumbs = computed<Breadcrumb[]>(() => {
|
||||
const pathWithoutLang = route.path.replace(`/${loc}`, '')
|
||||
const segments = pathWithoutLang.split('/').filter(Boolean)
|
||||
|
||||
// Ausnahme 1: /projekt/:slug → /references
|
||||
if (segments.length === 2 && segments[0] === 'projekt') {
|
||||
const referencesPath = i18nPages.references?.[loc] || '/references'
|
||||
|
||||
// Übersetzung für "references" holen, Fallback zu englisch falls nicht vorhanden
|
||||
const referencesLabel = t('references') || 'References'
|
||||
|
||||
const first = {
|
||||
@ -77,6 +76,28 @@ const breadcrumbs = computed<Breadcrumb[]>(() => {
|
||||
return [first, second]
|
||||
}
|
||||
|
||||
// Ausnahme 2: /artikel/:slug → /magazin
|
||||
if (segments.length === 2 && segments[0] === 'artikel') {
|
||||
const magazinePath = i18nPages.magazin?.[loc] || '/magazin'
|
||||
const magazineLabel = t('magazin') || 'Magazin'
|
||||
|
||||
const first = {
|
||||
label: magazineLabel,
|
||||
labelFull: magazineLabel,
|
||||
to: buildUrl(loc, magazinePath)
|
||||
}
|
||||
|
||||
const { label, labelFull } = formatLabel(segments[1])
|
||||
const second = {
|
||||
label,
|
||||
labelFull,
|
||||
to: route.path
|
||||
}
|
||||
|
||||
return [first, second]
|
||||
}
|
||||
|
||||
// Standard-Fall
|
||||
let path = ''
|
||||
return segments.map(segment => {
|
||||
path += '/' + segment
|
||||
@ -88,6 +109,7 @@ const breadcrumbs = computed<Breadcrumb[]>(() => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
40
components/TrackingScripts.vue
Normal file
40
components/TrackingScripts.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<!-- intentionally empty -->
|
||||
</template>
|
||||
<script setup>
|
||||
if (import.meta.client) {
|
||||
useHead({
|
||||
script: [
|
||||
{
|
||||
innerHTML: `
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
|
||||
_paq.push(["setCookieDomain", "*.digimedialoop.de"]);
|
||||
_paq.push(["disableCookies"]);
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u = "//analytics.digimedialoop.de/";
|
||||
_paq.push(['setTrackerUrl', u + 'matomo.php']);
|
||||
_paq.push(['setSiteId', '1']);
|
||||
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
|
||||
g.async = true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s);
|
||||
})();
|
||||
`,
|
||||
type: 'text/javascript',
|
||||
charset: 'utf-8',
|
||||
// Optional: ID zum gezielten Sanitizer deaktivieren
|
||||
hid: 'matomo-script'
|
||||
},
|
||||
{
|
||||
src: 'https://umami.digimedialoop.de/script.js',
|
||||
defer: true,
|
||||
'data-website-id': '7f521c0f-28b8-4ca8-82bf-150a34e14da6'
|
||||
}
|
||||
],
|
||||
__dangerouslyDisableSanitizersByTagID: {
|
||||
'matomo-script': ['innerHTML']
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@ -9,7 +9,7 @@
|
||||
aria-hidden="true"
|
||||
style="
|
||||
transform: scaleY(-1) scaleX(-1) translateY(99%);
|
||||
fill: rgba(38, 38, 38, 0.95);
|
||||
fill: rgba(38, 38, 38, 1);
|
||||
"
|
||||
>
|
||||
<g clip-path="url(#_clipPath_5kVoellZ93LI5Lc2i2b27JZsraaBm0XM)">
|
||||
@ -38,7 +38,7 @@
|
||||
{{ companyinfo?.postalcode }}
|
||||
{{ companyinfo?.city }}
|
||||
</p>
|
||||
<p><i>{{ companyinfo?.district }}</i></p>
|
||||
<p><i>({{ $t('districtSta') }} | {{ $t('upperBavaria') }})</i></p>
|
||||
<br >
|
||||
<p v-if="false" class="mb-4">
|
||||
<span class="icon">
|
||||
@ -154,7 +154,7 @@
|
||||
|
||||
<style lang="sass">
|
||||
footer
|
||||
background: rgba(38,38,38,.95)
|
||||
background-image: linear-gradient(to top , rgba(15, 15, 15, 1), rgba(38, 38, 38, 1))
|
||||
position: relative
|
||||
width: 100vw
|
||||
color: white
|
||||
|
||||
@ -49,14 +49,14 @@ export const i18nPages = {
|
||||
tr: '/projekt/:link'
|
||||
}
|
||||
},
|
||||
/*designer: {
|
||||
de: '/webentwicklung-fuer-designer-und-mediengestalter',
|
||||
en: '/web-development-for-designers-and-media-creators',
|
||||
fr: '/developpement-web-pour-designers-et-createurs-de-medias',
|
||||
it: '/sviluppo-web-per-designer-e-creativi-multimediali',
|
||||
es: '/desarrollo-web-para-disenadores-y-creadores-de-medios',
|
||||
tr: '/tasarimcilar-ve-medya-uzmanlari-icin-web-gelistirme'
|
||||
},*/
|
||||
designer: {
|
||||
de: '/designer',
|
||||
en: '/designers',
|
||||
fr: '/createurs',
|
||||
it: '/designer',
|
||||
es: '/disenadores',
|
||||
tr: '/tasarimcilar'
|
||||
},
|
||||
privacy: {
|
||||
de: '/datenschutz',
|
||||
en: '/privacy',
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
{
|
||||
"welcome": "Willkommen",
|
||||
"districtSta": "Landkreis Starnberg",
|
||||
"upperBavaria": "Oberbayern",
|
||||
"webagency": "Webagentur",
|
||||
"services": "Leistungen",
|
||||
"contact": "Kontakt",
|
||||
@ -56,9 +58,9 @@
|
||||
"pages": {
|
||||
"home": {
|
||||
"heroBox": {
|
||||
"h1": "Ihre Agentur für individuelles Webdesign und professionelle Webentwicklung",
|
||||
"h2": "Modulare Webseiten mit modernsten Technologien",
|
||||
"h3": "Höchste Performanz - schnell, effizient und zukunftssicher!"
|
||||
"h1": "Modulare Weblösungen für Ihren Erfolg",
|
||||
"h2": "Wir entwickeln performante Websites mit Fokus auf Skalierbarkeit, Wartbarkeit und Sichtbarkeit",
|
||||
"h3": "Wir bringen Ihre digitale Infrastruktur auf ein neues Level."
|
||||
},
|
||||
"solution": {
|
||||
"title": "Performance, KI-Kompatibilität & Barrierefreiheit",
|
||||
@ -178,6 +180,13 @@
|
||||
"teaser1": "In unserem Wissensbereich zeigen wir, worauf es bei Suchmaschinen-Optimierung, Barrierefreiheit, Webdesign, Webperformance und Online-Marketing ankommt.",
|
||||
"teaser2": "Entdecken Sie aktuelle Trends und praxisnahe Tipps, um Ihre Online-Präsenz gezielt zu stärken.",
|
||||
"readmore": "Artikel lesen"
|
||||
},
|
||||
"article": {
|
||||
"artikelUebersicht": "Artikelübersicht",
|
||||
"autor": "Autor:",
|
||||
"aktualisiert": "Aktualisiert am:",
|
||||
"ladenOderNichtGefunden": "Der Artikel wird geladen oder wurde nicht gefunden.",
|
||||
"kontaktieren": "Jetzt kontaktieren"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
<!-- layouts/default.vue -->
|
||||
<template>
|
||||
<div>
|
||||
<ClientOnly>
|
||||
<TrackingScripts />
|
||||
</ClientOnly>
|
||||
<PageHeader />
|
||||
<ContactForm />
|
||||
<BackToTopBtn />
|
||||
@ -14,9 +17,11 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { usePageMeta } from '~/composables/usePageMeta'
|
||||
|
||||
usePageMeta()
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
@ -103,7 +108,7 @@ main
|
||||
.loopShape
|
||||
border-radius: $loopShape
|
||||
|
||||
button
|
||||
button, .btn
|
||||
background-color: white
|
||||
border: 1px solid $darkgrey
|
||||
border-radius: 5px
|
||||
@ -115,6 +120,7 @@ main
|
||||
transition: all 0.4s ease-in-out
|
||||
z-index: 1
|
||||
color: $darkgrey
|
||||
text-decoration: none
|
||||
&::before
|
||||
content: ''
|
||||
position: absolute
|
||||
|
||||
25
pages/[...all].vue
Normal file
25
pages/[...all].vue
Normal file
@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<section>
|
||||
<div class="container-20 topSpace">
|
||||
<h1>Seite nicht gefunden (404)</h1>
|
||||
<h2>Sorry, diese Seite gibt es nicht</h2>
|
||||
<p>
|
||||
Aber ganz ehrlich: Wenn du eine High-Speed-Website willst, die wirklich performt und Besucher begeistert, bist du hier genau richtig.<br>
|
||||
</p><p>
|
||||
Wir setzen dich nicht nur ins Netz – wir bringen dich nach vorne.
|
||||
</p>
|
||||
<NuxtLink to="/" class="btn mintBtn" aria-label="Zur Startseite">
|
||||
Zur Startseite
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// Nuxt 3 behandelt den 404-Status automatisch
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
|
||||
</style>
|
||||
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="article" v-if="article">
|
||||
<SideBarNaviSlider link="/wissenswertes">
|
||||
{{ $t('artikel.artikelUebersicht') /* Beispiel für i18n */ }}
|
||||
{{ $t('pages.article.artikelUebersicht') }}
|
||||
</SideBarNaviSlider>
|
||||
|
||||
<section class="teaserBox topSpace">
|
||||
<div class="container-10">
|
||||
<p class="articleInfo">
|
||||
<b>{{ $t('artikel.autor') }}</b> {{ author }} |
|
||||
<b>{{ $t('artikel.aktualisiert') }}</b> {{ formattedDate }}
|
||||
<b>{{ $t('pages.article.autor') }}</b> {{ author }} <!--|
|
||||
<b>{{ $t('pages.article.aktualisiert') }}</b> {{ formattedDate }}-->
|
||||
</p>
|
||||
|
||||
<NuxtImg
|
||||
@ -25,7 +25,6 @@
|
||||
/>
|
||||
|
||||
<h1>{{ article.header }}</h1>
|
||||
|
||||
<p class="teaser">{{ article.teaser }}</p>
|
||||
</div>
|
||||
</section>
|
||||
@ -38,16 +37,17 @@
|
||||
role="button"
|
||||
aria-label="Kontakt aufnehmen"
|
||||
>
|
||||
{{ $t('kontakt.kontaktieren') }}
|
||||
{{ $t('pages.article.kontaktieren') }}
|
||||
</button>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div v-else class="container topSpace">
|
||||
<p>{{ $t('artikel.ladenOderNichtGefunden') }}</p>
|
||||
<p>{{ $t('pages.article.ladenOderNichtGefunden') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<Recommendations />
|
||||
<section class="contrastCalcLink">
|
||||
<section class="contrastCalcLink" v-if="false">
|
||||
<div class="container">
|
||||
<img src="https://strapi.digimedialoop.de/uploads/wcag_kontrastrechner_77abf9d9be.png" alt="kontrast check" class="imgRight">
|
||||
<p class="supheadlinePink">Barrierefreies Webdesign</p>
|
||||
|
||||
@ -180,7 +180,7 @@ const logoItems = computed(() => {
|
||||
@media (max-width: $breakPointMD)
|
||||
max-width: 100%
|
||||
h1
|
||||
margin-top: 0
|
||||
margin-top: 3rem
|
||||
font-size: clamp(2rem, 1.4rem + 3vw, 2.8rem)
|
||||
margin-bottom: 0
|
||||
font-family: 'Comfortaa'
|
||||
@ -195,7 +195,7 @@ const logoItems = computed(() => {
|
||||
position: relative
|
||||
overflow: hidden
|
||||
min-height: 400px
|
||||
margin: 5vh 0
|
||||
margin: 2vh 0 8vh 0
|
||||
padding: 8vh 0
|
||||
|
||||
.background-image
|
||||
|
||||
@ -85,20 +85,20 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--<section class="grafiker">
|
||||
<section class="grafiker">
|
||||
<div class="container">
|
||||
<p class="supheadlineMint">{{ $t('pages.webagency.grafiker.supheadline') }}</p>
|
||||
<h2>{{ $t('pages.webagency.grafiker.title') }}</h2>
|
||||
<button
|
||||
class="mintBtn"
|
||||
@click.prevent="navigateTo(localePath({ name: 'designer' }))"
|
||||
@click.prevent="navigateTo(designerLink)"
|
||||
role="button"
|
||||
aria-label="Zum Angebot für Kreative"
|
||||
>
|
||||
{{ $t('pages.webagency.grafiker.button') }}
|
||||
</button>
|
||||
</div>
|
||||
</section>-->
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -109,6 +109,11 @@ import { useMainStore } from "@/stores/main";
|
||||
import { computed } from "vue";
|
||||
import { useRouter } from "nuxt/app";
|
||||
|
||||
import { i18nPages } from '@/i18n/i18n-pages'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { locale } = useI18n()
|
||||
const designerLink = i18nPages.designer?.[locale.value] || '/designer'
|
||||
|
||||
const mainStore = useMainStore();
|
||||
const { companyinfo } = storeToRefs(mainStore);
|
||||
const toggleContactBubble = () => mainStore.toggleContactBubble();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user