Courier Newsrooms

Project Detail

Courier Newsroom

Project summary :

Courier Newsroom publishes state-focused local news across a WordPress multisite network. I worked on it through two eras: first a legacy network of about a dozen sites on WP Engine and Divi, where I built the tools off-the-shelf plugins couldn’t provide, then the rebuild onto WordPress VIP with Alley Interactive, where I shipped production code on an enterprise stack as the network grew to 21 sites on one shared codebase.

Objectives

#GoalResult
1Get mobile performance out of the red on both platformsMobile PageSpeed [40s → 90s] on the legacy network; TBT ~4.3s → ~774ms on VIP
2Give editors tools the legacy stack couldn’tCustom plugins for forms, video automation, newsletter gates, and content queries
3Make every newsletter signup real and attributablereCAPTCHA v3 + honeypot network-wide; UTMs, referrer, and GA4 client ID passed to Sailthru
4Clean up search and traffic data~1,440 indexed 404s resolved; ~91K botnet pageviews traced and blocked

Across both phases I kept the network publishing daily while the platform underneath it was rebuilt, sped up, and cleaned up, then helped scale it to 21 sites without a single site-specific fork.

AreaKey Deliverables
FormsCourier Dynamic Forms: one plugin replacing per-site forms across 11 domains, with auto-generated shortcodes, automatic domain detection, and layered spam protection
Newsletter GatesGates Manager: centralized gate rules on top of OptinMonster, which has no rules API. One JS-variable rule per campaign, a hard/soft priority hierarchy, and per-newsletter cookies parsed from Sailthru lists, replacing hand-edits across 165+ campaign rule sets
VideoEX.CO plugins: an embed manager that detects player type from the pasted embed code, and a post creator using HMAC-signed API calls to draft video posts with featured images and duplicate detection
Content ModulesJB Query Builder: reusable query modules placed by shortcode, with page-wide duplicate prevention and AJAX pagination that keeps taxonomy context
PerformanceAudited ~60 third-party domains; deferred non-critical assets to first interaction; preloaded the LCP image with fetchpriority and fixed an LCP redirect chain through the CDN
Consent & FeedsMigrated consent management to InMobi CMP across 11+ sites; built a SmartNews RSS plugin and fixed an injected script breaking feed validation
TaxonomyBuilt a multisite taxonomy analyzer and consolidated tags network-wide, e.g. five slug variants of "2024 election" merged into one
AreaKey Deliverables
ArchitectureFeatures as classes behind a shared Feature interface; per-site config through a Newsroom enum and PHP match(), so one codebase serves every site with no forks
PlatformGitHub to VIP CI deploys across develop, preprod, and production; PHPCS (VIP standards), PHPStan, and Rector; VIP CLI and WP-CLI for network-wide operations
Custom BlocksInteractive map block with Google Places autofill; per-site ActBlue donation block; Curator social embeds; curated query pagination
LaunchesNew state sites added through shared config: enum case, domain mapping, color palette, redirects, and site setup
  • Interaction gate – holds the ad stack (Aditude, GTM, Meta Pixel, Sailthru, jQuery) until first interaction, neutralizing script tags server-side with a MutationObserver fallback for dynamically injected tags.

  • Image delivery – quality tuning on photo sizes and corrected responsive sizes attributes, which had been silently doing nothing.

  • Tag Manager delay – GTM moved behind an inline interaction listener with a 5-second fallback.

  • Measured, not guessed – DevTools request-blocking tests isolated each third party's real cost, identifying duplicate GA4 property loads as the largest remaining blocking cost.

  • 410 handler – share-button redirect URLs were being indexed as 404s; returning 410 Gone resolved ~1,440 of them.

  • Breadcrumbs restored – a plugin update had silently switched breadcrumb schema off on every site; found in Search Console and restored network-wide.

  • Video schema – VideoObject completed with contentUrl and duration from EX.CO metadata so video posts qualify for rich results.

  • reCAPTCHA v3 on HTMX – one htmx:confirm gate for every signup form, fail-closed, loaded only when the email field is focused. Honeypot widened network-wide.

  • Silent signup failure – traced failing signups to an invalid Sailthru API key and rotated credentials on every production site via WP-CLI.

  • Attribution – UTMs, landing referrer, signup type, and GA4 client ID captured client-side (VIP's page cache rules out server sessions) and passed to Sailthru; conversion events pushed to the dataLayer on success only.

  • Botnet investigation – 13 tag pages drew ~91K of ~108K views with zero engagement; traced through server logs to a datacenter botnet using a fake Chrome user agent, then blocked it and noindexed the targets.

Courier Newsroom operates [21] state-focused news sites on one WordPress VIP multisite:

StateSite URL
Arizonacoppercourier.com
Californiacouriercalifornia.com
Coloradocouriercolorado.com
Georgiacouriergeorgia.com
Iowaiowastartingline.com
Kentuckyhellbendernewsroom.com
Michigangandernewsroom.com
Minnesotacouriermn.com
Nebraskacouriernebraska.com
Nevadathenevadannews.com
New Hampshiregranitepostnews.com
New Mexicocouriernewmexico.com
New Yorkcourierny.com
North Carolinacardinalpine.com
Pennsylvaniakeystonenewsroom.com
Texascouriertexas.com
Utahutahjunction.com
Virginiavadogwood.com
Wisconsinupnorthnewswi.com

Performance Gains

Metric Before After Δ
Mobile PageSpeed (legacy network) 40s 90s 50 pts
Mobile PageSpeed (VIP) 30s 90s 60 pts
Total Blocking Time (VIP) ~4.3 s ~774 ms −82%
Indexed 404s ~1,440 Resolved 410 Gone
Botnet pageviews ~91K Blocked IP + UA filtering
Client Details

Courier Newsroom​

Service Provided

Courier Newsroom WordPress VIP development, legacy network maintenance, custom plugins & blocks, performance engineering, technical SEO, analytics & attribution, bot mitigation.

Project timeline

Over a 3 Years of Development October 2023 – October 2026

Leave a Reply

Your email address will not be published. Required fields are marked *