Skip to content

Migrating to GA4, swapping in Google Tag Manager, and renaming the site to steven.ocampo.io

Universal Analytics is on the way out, so this PR migrates to GA4 via Google Tag Manager loaded through next/script, and renames everything from stevieismagic.com to steven.ocampo.io.

2 min readEvergreen

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/script handles 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.js and 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 to steven.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).


PR: https://github.com/StevieIsmagic/vercel_blog/pull/3