Most portfolios sit there and look pretty. Mine tracks who’s reading, what they click, and which version of my resume is landing. When editing eight pages by hand got old, I wrote a plugin to do it for me. Here’s what’s underneath.
I wrote ~8,700 lines to ship the static site. Then I wrote ~14,000 more to build the plugin that runs it. Custom architecture costs more upfront. It pays back every edit.
CSS custom properties for the palette so every page stays in sync. Tracking script pushes structured events to dataLayer — eight of them:
Mobile-first with fluid type. WCAG AA contrast. JSON-LD on every page so Google connects the work to the candidate.
First draft going up now.
Static HTML is fast. Editing eight pages by hand after the third rewrite is not. So I designed a custom WordPress plugin — every page on this site renders through it, every section is editable from a real admin dashboard. No Elementor. No theme. No shortcode soup. Just PHP and a clean data model.
Eight pages from scratch. Design system, typography, motion, accessibility — all written by hand and pushed to Bluehost. Worked. Didn’t scale.
Moved everything to WordPress on the Hello Elementor theme. Full-width template, raw HTML inside each page. Live, but every edit was still a copy-paste.
Real WordPress plugin. Admin editor, versioned migrations, 20+ reusable section types. I edit the site through a dashboard I designed. Currently at v3.0.24.
Every case study uses the same schema. Sections snap on or off per page — hero, numbers, gallery, video, campaign callout, before/after, takeaway. Add a new section type once, every page can use it.
Every plugin update runs a versioned migration that patches existing data without overwriting edits. 24 of them shipped. The site never went down once.
A real Messenger conversation that types itself out on a loop — pure CSS, no JavaScript, no third-party widget. I used it to recreate an actual booking thread for Tami’s Tasty Tables.
Real campaign metrics rendered as interactive SVG — animated line charts, summary tiles, hover states. Used on Holding Them Accountable to show GroundTruth daily reach without embedding a screenshot that’ll rot.
Three IAB banner sizes shown inside actual phone and browser frames — so a recruiter sees the ad the way it ran, not as a flat 320×50 floating in space. Animated slide-in, scrolling skeleton page.
Email, LinkedIn, social, and web stats rendered as native HTML cards — not screenshots from a dashboard that expires next month. Editable. Always sharp. Never broken.
When LinkedIn, Facebook, or Instagram block their iframe embeds, the renderer falls back to a styled thumbnail card that links to the post. Reliable over fragile. Always.
Each case study gets its own brand palette — hero, accents, callouts all painted from one variable set. Set the color once, the page renders itself. No global theme switch.
A portfolio that can’t track itself can’t prove anything. So I tracked everything.
Five colors. Two typefaces. Hard borders. Offset shadows. CSS custom properties so every page stays in sync — change one variable, every page updates. Fraunces for headlines because nothing else moves like it. Space Mono for the UI because labels need to feel like labels.
Real WordPress plugin running the whole site. Hero, numbers, gallery, video, campaign callout, before/after, takeaway — every section is its own type, editable from an admin dashboard I designed. Sections snap on or off per page. No Elementor.
Person, WebSite, WebPage, ProfilePage, CreativeWork — every page ships with structured data linked to one Person ID so Google connects the work to the candidate. Open Graph and Twitter Card meta everywhere. No Yoast required.
Google Tag Manager fires on every page load with a noscript fallback. One GA4 config tag, plus custom event tags pulling every dataLayer push. Form submissions and resume downloads marked as Key Events — the conversions that actually matter for a job hunt.
One tracking script handles email clicks, phone taps, resume downloads, LinkedIn opens, Spotify plays, form submits, and Formspree confirmations. Each event carries link location, click text, page path. Segmentation in GA4 means something — not just a pile of clicks.
Every resume placement gets its own UTM-tagged URL — source, medium, campaign, content. The PDF in my email signature is tagged differently than the one on LinkedIn, which is tagged differently than the one on this site. Different versions can be A/B-tested by source. Marketing applied to my own job hunt.
Recruiters open portfolios on their phones on the way home from work. Every page is responsive by default — fluid typography, tap targets sized for thumbs, lazy-loaded iframes, system-font fallbacks while the web fonts load. ARIA labels on form fields, semantic landmarks for screen readers, focus-visible states for keyboard nav, contrast that clears WCAG AA. The site has to work everywhere, or it doesn’t work anywhere.
Every interaction worth tracking pushes a structured event into the GTM dataLayer. GTM routes them to GA4. The ones that matter — form submits, resume downloads — are flagged as Key Events. That’s GA4’s word for conversion.
The script is about 120 lines. GA4-compliant: parameter values clipped to 100 characters, snake_case throughout, and a separate contact_form_confirmed event that only fires after Formspree’s success redirect. The conversion count reflects delivered messages, not just submit clicks.
What’s firing, right column.
// dataLayer events firing on this site window.dataLayer.push({ event: 'contact_form_submit', form_topic: 'Hiring', link_location: 'contact-form', page_path: '/contact' }); // All tracked event names: page_loaded email_click phone_click resume_download // ★ Key Event linkedin_click spotify_click contact_form_submit contact_form_confirmed // ★ Key Event
Every place my resume lives gets its own UTM-tagged URL. When a hiring manager clicks, GA4 tells me where it came from — and which version they got. Different resumes can be A/B-tested by source.
The marketers who pull ahead are the ones who learned how to build, not just how to brief. Strategy is sharper when you’ve seen how it gets shipped.