Two things in one PR because they touched the same files: the analytics migration from Universal Analytics to GA4, and a site-wide rename from stevieismagic.com to steven.ocampo.io.
GA4 via GTM, loaded through next/script
Universal Analytics was being sunset by Google and my PR #1 wiring had me on the old gtag('config', UA-ID) path. Time to migrate.
Approach this time: instead of calling gtag directly, I load Google Tag Manager via Next.js's built-in next/script component with strategy="afterInteractive". GTM then owns the GA4 tag configuration on the GTM dashboard side, not in the codebase. Benefits:
- Swapping GA4 for something else later (Plausible, PostHog, Fathom) is a dashboard change, not a redeploy.
next/scripthandles loading strategy properly — I don't need to hand-write<script async>tags or worry about placement.- Tag config lives in one place (GTM), not split between
pages/_document.jsand a lib file.
<Script id="google-tag-manager" strategy="afterInteractive">
{`
(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start': new Date().getTime(), event:'gtm.js'});
…
})(window,document,'script','dataLayer','${process.env.NEXT_GOOGLE_TAG_MANAGER_ID}');
`}
</Script>Rename: stevieismagic.com → steven.ocampo.io
I've been shifting my personal identity online from the "Stevie IsMagic" brand (which is fine but juvenile for the kind of writing I want to do) to a plainer steven.ocampo.io. This PR does the rename in the places that matter for this blog:
README.md— title updated tosteven.ocampo.io.app/layout.tsx— site metadata, OG title, siteName, canonical URL, all OG image URLs.app/blog/[slug]/page.tsx— per-post OG image URL generation and per-post canonical URL.
Three spots for the OG image URL because the site has three different code paths that emit them (homepage OG, per-post OG, per-post fallback to an auto-generated OG at /api/og?title=…). Missed one of them in the initial sweep and had to come back.
Carryover: the layout still says "Stevie IsMagic" in one place
The sidebar <Logo> component still reads aria-label="Stevie IsMagic". I noticed it after the diff was open and decided to leave it for a later PR so this one stays focused on the analytics + metadata rename. PR #6 comes back for the sidebar.
Test plan
- Merge, let Vercel redeploy.
- Check network tab for GTM script loading.
- Check GA4 dashboard for incoming pageviews after a few minutes.
- Check canonical URLs in page source for a couple of posts.
- Check the OG image URLs by running the page through the Facebook Sharing Debugger.
There's one CSP wrinkle about to show up — adding GTM to the page triggers a Content-Security-Policy violation because googletagmanager.com isn't in the script-src allowlist. PR #4 fixes that (and PR #5 fixes a typo in the fix).