From 765ebdca6e33b41d4867b9a6ea13dcdf128da169 Mon Sep 17 00:00:00 2001 From: Guilherme Biff Zarelli Date: Wed, 28 Oct 2026 15:08:36 -0300 Subject: [PATCH] feat(adsense): add responsive site-wide ad unit --- .github/workflows/deploy.yml | 3 + .../plans/2026-10-28-adsense-footer-slot.md | 45 ++++++++ .../2026-10-28-adsense-footer-slot-design.md | 41 +++++++ src/app/components/AdSenseBanner/index.tsx | 49 ++++++++ src/app/components/Footer/index.tsx | 1 + src/app/layout.tsx | 12 ++ src/app/privacidade/page.tsx | 109 ++++++++++++++++++ src/app/sitemap.ts | 1 + 8 files changed, 261 insertions(+) create mode 100644 docs/superpowers/plans/2026-10-28-adsense-footer-slot.md create mode 100644 docs/superpowers/specs/2026-10-28-adsense-footer-slot-design.md create mode 100644 src/app/components/AdSenseBanner/index.tsx create mode 100644 src/app/privacidade/page.tsx diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f5fc504..65daba6 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -11,6 +11,9 @@ jobs: build: runs-on: ubuntu-latest environment: deploy + env: + NEXT_PUBLIC_ADSENSE_CLIENT_ID: ${{ vars.NEXT_PUBLIC_ADSENSE_CLIENT_ID }} + NEXT_PUBLIC_ADSENSE_SLOT_ID: ${{ vars.NEXT_PUBLIC_ADSENSE_SLOT_ID }} steps: - name: Checkout code diff --git a/docs/superpowers/plans/2026-10-28-adsense-footer-slot.md b/docs/superpowers/plans/2026-10-28-adsense-footer-slot.md new file mode 100644 index 0000000..14f588a --- /dev/null +++ b/docs/superpowers/plans/2026-10-28-adsense-footer-slot.md @@ -0,0 +1,45 @@ +# AdSense Footer Slot Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add one responsive, discreet AdSense slot after each route’s content and before the shared footer. + +**Architecture:** A client component reads the publisher and slot IDs from public build-time environment variables. The root layout loads the AdSense verification script in the document head and places the ad component between route content and the global footer. A site privacy page documents AdSense cookies and ad personalization. + +**Tech Stack:** Next.js 15 App Router, React 19, TypeScript, Tailwind CSS. + +**Spec:** `docs/superpowers/specs/2026-10-28-adsense-footer-slot-design.md` + +## Global Constraints + +- Keep ads off when either `NEXT_PUBLIC_ADSENSE_CLIENT_ID` or `NEXT_PUBLIC_ADSENSE_SLOT_ID` is missing. +- Do not add Auto Ads, sticky ads, or overlays. +- Do not invent account IDs. +- Store the AdSense IDs as GitHub Actions variables in the `deploy` environment. +- Configure both GitHub variables before the release build so the unit appears on every route. +- The repository has no configured test suite; run `npm run build` as the validation command. + +## Review Focus + +- Missing either ID must not render an empty advertising container. +- Load the verification script only when the publisher ID is present; initialize the ad slot only when both IDs are present. +- The unit must remain responsive on narrow screens. +- The slot must remain after the route content and before the shared footer. +- Initialization must not run more than once during normal navigation. + +--- + +### Task 1: Add the global AdSense slot + +**Files:** +- Create: `src/app/components/AdSenseBanner/index.tsx` +- Modify: `src/app/layout.tsx` + +**Interfaces:** +- Consumes: `NEXT_PUBLIC_ADSENSE_CLIENT_ID` and `NEXT_PUBLIC_ADSENSE_SLOT_ID`. +- Produces: `AdSenseBanner`, a default-exported React component rendered once by the root layout. + +- [ ] Add a client component that returns `null` until both IDs are present. +- [ ] Load the AdSense verification script in the root document head and initialize one responsive slot with the “Anúncio” label. +- [ ] Render the component between `{children}` and `