Add two new ad formats to blog articles for increased revenue
Integrates an interstitial overlay ad and a parallax ad into article pages to display advertisements. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 23852c00-4779-460a-9e0c-d09fee4b6c92 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 3158e283-294f-4fb9-b342-6bff6c7c14cc Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/23852c00-4779-460a-9e0c-d09fee4b6c92/tdiozLO Replit-Helium-Checkpoint-Created: true
This commit is contained in:
parent
f653a15043
commit
c70a63f5c3
66
client/src/components/interstitial-ad.tsx
Normal file
66
client/src/components/interstitial-ad.tsx
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { X } from "lucide-react";
|
||||||
|
import AdSense from "./adsense";
|
||||||
|
|
||||||
|
const COUNTER_KEY = "folx-interstitial-count";
|
||||||
|
const DELAY_MS = 3000;
|
||||||
|
|
||||||
|
export default function InterstitialAd() {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const raw = sessionStorage.getItem(COUNTER_KEY);
|
||||||
|
const count = raw ? parseInt(raw, 10) : 0;
|
||||||
|
const next = count + 1;
|
||||||
|
sessionStorage.setItem(COUNTER_KEY, next.toString());
|
||||||
|
|
||||||
|
const shouldShow = next % 2 === 1;
|
||||||
|
if (!shouldShow) return;
|
||||||
|
|
||||||
|
const timer = setTimeout(() => setVisible(true), DELAY_MS);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (visible) {
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
document.body.style.overflow = "";
|
||||||
|
};
|
||||||
|
}, [visible]);
|
||||||
|
|
||||||
|
if (!visible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/70 animate-in fade-in duration-300"
|
||||||
|
onClick={() => setVisible(false)}
|
||||||
|
data-testid="interstitial-ad-overlay"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="relative bg-card rounded-xl shadow-2xl w-[90vw] max-w-lg p-6"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
data-testid="interstitial-ad-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={() => setVisible(false)}
|
||||||
|
className="absolute top-3 right-3 z-10 w-8 h-8 flex items-center justify-center rounded-full bg-muted hover:bg-muted/80 text-foreground transition-colors"
|
||||||
|
data-testid="button-interstitial-close"
|
||||||
|
aria-label="Schließen"
|
||||||
|
>
|
||||||
|
<X className="w-5 h-5" />
|
||||||
|
</button>
|
||||||
|
<div className="text-[10px] text-muted-foreground/40 text-center mb-2 uppercase tracking-widest">Anzeige</div>
|
||||||
|
<div className="min-h-[250px] flex items-center justify-center">
|
||||||
|
<AdSense
|
||||||
|
slot="4154017639"
|
||||||
|
format="rectangle"
|
||||||
|
responsive={false}
|
||||||
|
style={{ display: "inline-block", width: "300px", height: "250px" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
19
client/src/components/parallax-ad.tsx
Normal file
19
client/src/components/parallax-ad.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import AdSense from "./adsense";
|
||||||
|
|
||||||
|
export default function ParallaxAd() {
|
||||||
|
return (
|
||||||
|
<div className="relative" data-testid="parallax-ad-wrapper">
|
||||||
|
<div className="sticky top-0 h-[350px] flex items-center justify-center bg-background z-0">
|
||||||
|
<div className="text-center w-full max-w-lg mx-auto">
|
||||||
|
<div className="text-[10px] text-muted-foreground/40 text-center mb-2 uppercase tracking-widest">Anzeige</div>
|
||||||
|
<AdSense
|
||||||
|
slot="2398082838"
|
||||||
|
format="rectangle"
|
||||||
|
style={{ display: "block", minHeight: "250px" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="h-[350px]" aria-hidden="true" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -12,6 +12,8 @@ import Footer from "@/components/footer";
|
|||||||
import { InArticleAd, PageSideAds } from "@/components/adsense";
|
import { InArticleAd, PageSideAds } from "@/components/adsense";
|
||||||
import DOMPurify from "dompurify";
|
import DOMPurify from "dompurify";
|
||||||
import ShareButtons from "@/components/share-buttons";
|
import ShareButtons from "@/components/share-buttons";
|
||||||
|
import InterstitialAd from "@/components/interstitial-ad";
|
||||||
|
import ParallaxAd from "@/components/parallax-ad";
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } from "react";
|
||||||
|
|
||||||
const ALLOWED_IFRAME_DOMAINS = [
|
const ALLOWED_IFRAME_DOMAINS = [
|
||||||
@ -337,7 +339,9 @@ export default function ArticlePage() {
|
|||||||
|
|
||||||
<RelatedArticles currentSlug={slug || ""} />
|
<RelatedArticles currentSlug={slug || ""} />
|
||||||
</main>
|
</main>
|
||||||
|
<ParallaxAd />
|
||||||
<Footer narrow />
|
<Footer narrow />
|
||||||
|
<InterstitialAd />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,8 @@ The official website for Folx Music Television (folx.tv). Dark-themed bento grid
|
|||||||
- Recipe widget + full /rezepte subpage (21 recipes across 5 regions: Österreich, Bayern, Schwaben/Baden, Südtirol/Alpen, Norddeutschland) with AI-generated images
|
- Recipe widget + full /rezepte subpage (21 recipes across 5 regions: Österreich, Bayern, Schwaben/Baden, Südtirol/Alpen, Norddeutschland) with AI-generated images
|
||||||
- Google News RSS widget (Volksmusik/Schlager news, 5 items, auto-rotate)
|
- Google News RSS widget (Volksmusik/Schlager news, 5 items, auto-rotate)
|
||||||
- Google AdSense integration (ca-pub-4465464714854276)
|
- Google AdSense integration (ca-pub-4465464714854276)
|
||||||
|
- Interstitial overlay ad on article pages (3s delay, shows every other article visit, sessionStorage counter)
|
||||||
|
- Parallax/reveal ad below article content (sticky background ad revealed on scroll)
|
||||||
- Web Push Notifications (bell icon in header, auto-send on new articles, admin panel at /admin/push)
|
- Web Push Notifications (bell icon in header, auto-send on new articles, admin panel at /admin/push)
|
||||||
- Article listing with featured carousel and category filtering
|
- Article listing with featured carousel and category filtering
|
||||||
- HTML content supports embedded iframes (bunny.net, YouTube, Facebook, Instagram, TikTok)
|
- HTML content supports embedded iframes (bunny.net, YouTube, Facebook, Instagram, TikTok)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user