feat(AppHeader): improve ad display logic and responsiveness
All checks were successful
Deploy to production / deploy (push) Successful in 2m58s

- Enhanced the AppHeader component to support separate ad slots for mobile and desktop views, improving ad display based on viewport width.
- Introduced a responsive design that adjusts ad dimensions and formats for better visibility across different screen sizes.
- Updated methods to dynamically determine the active ad slot and handle viewport resizing events for optimal ad rendering.
This commit is contained in:
Torsten Schulz (local)
2026-05-06 15:53:58 +02:00
parent 5993f79e7a
commit ab3e8d14e5

View File

@@ -10,12 +10,20 @@
</div> </div>
<div class="header-ad" v-if="showHeaderAd"> <div class="header-ad" v-if="showHeaderAd">
<ins <ins
v-if="isMobileAd"
key="header-ad-mobile"
class="adsbygoogle" class="adsbygoogle"
style="display:block" style="display:inline-block;width:320px;height:50px"
data-ad-client="ca-pub-1104166651501135" data-ad-client="ca-pub-1104166651501135"
:data-ad-slot="adSlotId" :data-ad-slot="activeAdSlotId"
data-ad-format="horizontal" ></ins>
data-full-width-responsive="false" <ins
v-else
key="header-ad-desktop"
class="adsbygoogle"
style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-1104166651501135"
:data-ad-slot="activeAdSlotId"
></ins> ></ins>
</div> </div>
<div class="header-meta"> <div class="header-meta">
@@ -60,6 +68,7 @@ export default {
data() { data() {
return { return {
adInitialized: false, adInitialized: false,
viewportWidth: typeof window !== 'undefined' ? window.innerWidth : 1280,
/** Endonyme: jede Sprache bezeichnet sich in ihrer eigenen Sprache. */ /** Endonyme: jede Sprache bezeichnet sich in ihrer eigenen Sprache. */
uiLocaleOptions: [ uiLocaleOptions: [
{ value: 'de', nativeLabel: 'Deutsch' }, { value: 'de', nativeLabel: 'Deutsch' },
@@ -89,7 +98,7 @@ export default {
}; };
}, },
showHeaderAd() { showHeaderAd() {
if (!this.adSlotId) { if (!this.activeAdSlotId) {
return false; return false;
} }
const path = this.$route?.path || ''; const path = this.$route?.path || '';
@@ -103,9 +112,27 @@ export default {
path.startsWith('/falukant/home') path.startsWith('/falukant/home')
); );
}, },
adSlotId() { desktopAdSlotId() {
const slot = String(import.meta.env.VITE_ADSENSE_HEADER_SLOT || '').trim(); const slot = String(
import.meta.env.VITE_ADSENSE_HEADER_SLOT_DESKTOP
|| import.meta.env.VITE_ADSENSE_HEADER_SLOT
|| ''
).trim();
return /^\d{6,}$/.test(slot) ? slot : ''; return /^\d{6,}$/.test(slot) ? slot : '';
},
mobileAdSlotId() {
const slot = String(
import.meta.env.VITE_ADSENSE_HEADER_SLOT_MOBILE
|| import.meta.env.VITE_ADSENSE_HEADER_SLOT
|| ''
).trim();
return /^\d{6,}$/.test(slot) ? slot : '';
},
isMobileAd() {
return this.viewportWidth < 960;
},
activeAdSlotId() {
return this.isMobileAd ? this.mobileAdSlotId : this.desktopAdSlotId;
} }
}, },
watch: { watch: {
@@ -116,9 +143,30 @@ export default {
this.$nextTick(() => this.initHeaderAd()); this.$nextTick(() => this.initHeaderAd());
} }
} }
},
isMobileAd(next, prev) {
if (next !== prev) {
this.adInitialized = false;
if (this.showHeaderAd) {
this.$nextTick(() => this.initHeaderAd());
}
}
}
},
mounted() {
if (typeof window !== 'undefined') {
window.addEventListener('resize', this.handleResize, { passive: true });
}
},
beforeUnmount() {
if (typeof window !== 'undefined') {
window.removeEventListener('resize', this.handleResize);
} }
}, },
methods: { methods: {
handleResize() {
this.viewportWidth = window.innerWidth;
},
initHeaderAd() { initHeaderAd() {
if (!this.showHeaderAd) return; if (!this.showHeaderAd) return;
if (this.adInitialized) return; if (this.adInitialized) return;
@@ -252,28 +300,26 @@ export default {
} }
.header-ad { .header-ad {
flex: 1 1 260px; flex: 1 1 728px;
min-width: 180px; min-width: 320px;
max-width: 560px; max-width: 728px;
min-height: 54px; min-height: 90px;
max-height: 54px; max-height: 90px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center;
overflow: hidden; overflow: hidden;
} }
.header-ad .adsbygoogle { .header-ad .adsbygoogle {
width: 100% !important; width: 100%;
height: 54px !important; max-width: 100%;
min-height: 54px !important;
max-height: 54px !important;
overflow: hidden !important; overflow: hidden !important;
} }
.header-ad :deep(iframe), .header-ad :deep(iframe),
.header-ad :deep([id^="aswift_"]) { .header-ad :deep([id^="aswift_"]) {
height: 54px !important; max-width: 100% !important;
max-height: 54px !important;
} }
.header-meta__context { .header-meta__context {
@@ -407,22 +453,26 @@ export default {
.header-ad { .header-ad {
order: 3; order: 3;
width: 100%; width: 100%;
max-width: none; max-width: 320px;
flex: 1 1 100%; flex: 1 1 100%;
min-height: 44px; min-height: 50px;
max-height: 44px; max-height: 50px;
} }
.header-ad .adsbygoogle { .header-ad .adsbygoogle {
height: 44px !important; width: 320px !important;
min-height: 44px !important; min-width: 320px !important;
max-height: 44px !important; max-width: 320px !important;
height: 50px !important;
min-height: 50px !important;
max-height: 50px !important;
} }
.header-ad :deep(iframe), .header-ad :deep(iframe),
.header-ad :deep([id^="aswift_"]) { .header-ad :deep([id^="aswift_"]) {
height: 44px !important; width: 320px !important;
max-height: 44px !important; height: 50px !important;
max-height: 50px !important;
} }
.header-meta { .header-meta {