// layout.tsx export const viewport: Viewport = { width: "device-width", initialScale: 1, themeColor: [ { media: "(prefers-color-scheme: light)", color: "white" }, { media: "(prefers-color-scheme: dark)", color: "#0f172a" }, ], }; export const metadata: Metadata = { metadataBase: new URL(env.NEXT_PUBLIC_APP_URL), title: { default: siteConfig.name, template: `%s | ${siteConfig.name}`, }, description: siteConfig.description, keywords: [ "Web Development Agency", "Professional Services", "Responsive Design", "E-commerce Solutions", "SEO Optimization", "Brand Identity", "Custom Design", "Digital Solutions", "User Experience", ], authors: [{ name: "Sun Sreng", url: "https://service.gmana.co" }], creator: "Sun Sreng", openGraph: { title: siteConfig.name, description: siteConfig.description, url: env.NEXT_PUBLIC_APP_URL, siteName: siteConfig.name, locale: "en_US", type: "website", images: [ { url: siteConfig.ogImage, width: 1200, height: 600, alt: siteConfig.name, }, ], }, robots: { index: true, follow: true, googleBot: { index: true, follow: true, "max-video-preview": -1, "max-image-preview": "large", "max-snippet": -1, }, }, twitter: { title: siteConfig.name, card: "summary_large_image", }, other: { "google-adsense-account": "ca-pub-xxxx", }, }; export default function RootLayout({ children }: PropsWithChildren) { return ( <html lang="en" suppressHydrationWarning className={cn(fontGmana.variable, fontSans.variable, fontMono.variable)}> <body className="min-h-scree font-sans text-base"> {children} <Script async src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${process.env.NEXT_PUBLIC_GOOGLE_ADS_CLIENT_ID}`} strategy="lazyOnload" crossOrigin="anonymous" ></Script> </body> </html> ); }
// ads-banner.tsx "use client"; import { useEffect, useRef } from "react"; declare global { interface Window { adsbygoogle: unknown[]; } } interface AdsBannerProps { "data-ad-slot": string; "data-ad-format": string; "data-full-width-responsive": string; "data-ad-layout"?: string; } const AdBanner = (props: AdsBannerProps) => { const adRef = useRef<HTMLModElement | null>(null); useEffect(() => { try { if (adRef.current && !adRef.current.dataset.adInitialized) { window.adsbygoogle = window.adsbygoogle || []; window.adsbygoogle.push({}); adRef.current.dataset.adInitialized = "true"; } } catch (err) { console.error("Error initializing ads: ", err); } }, []); return ( <ins ref={adRef} className="adsbygoogle adbanner-customize mt-2" style={{ display: "block", overflow: "hidden", border: process.env.NODE_ENV === "development" ? "1px solid red" : "none", }} data-adtest="on" data-ad-client={process.env.NEXT_PUBLIC_GOOGLE_ADS_CLIENT_ID} {...props} /> ); }; export default AdBanner;
// ads-blogs "use client"; import dynamic from "next/dynamic"; export const AdBlog = dynamic(() => import("@/components/ads/google-ads-unit"), { ssr: false, loading: () => null, // Optional: add a loading state if needed });
// blog.tsx <AdBlog data-ad-slot="xxxxx" data-full-width-responsive="true" data-ad-layout="in-article" data-ad-format="fluid" />
245 views