HR Connect Series 2026 — Campaign Command
End-to-end paid media workflow: Plan → Audience → Budget → Keywords → Ad Studio → Schedule → Approval → Report → Export. Built for brand-team handoff — every field is editable, every export is proposal-ready.
Campaign phases
Marketing funnel
Campaign Brief
Confirmed parameters from the approved plan. Brand person can edit any field — edits carry into every preview, calendar and export.
Campaign content pillars
Verified proof points use these — never invent
- Silver — Best Innovation for HR, HR Vendors of the Year 2024
- NTUC Club since 1986 · Company of Good (1 Heart), NVPC
- Owned venues: Downtown East · D'Marquee (~2,200 pax) · Wild Wild Wet · Orchid Country Club
- SMRT 10,000 staff / 3 yrs · UWEEI 2,500-pax Family Day · Playverse ~4,000
- Pillars: One-Stop Concierge · Real-Time Insights · Perfect Match
Campaign architecture — the stage for every ad
Theme → ad groups → ad content formats → funnel stage. Every creative in the Ad Studio inherits its key emphasis from this structure.
Budget Allocation & Pacing
Edit totals or splits — monthly pacing recalculates automatically.
Monthly pacing
Editing a month's total rescales the other 8 months proportionally so the 9-month total always stays at the approved plan amount.
Approved assets — spend per month auto-split from the pacing above · editable per ad
Every ad copy that has cleared Approval (Approved, Scheduled, Live or Ended) gets an automatic share of that month's LinkedIn/Google budget once it has flight dates. Set flights individually via Approval · 📅 Schedule, or apply the standard NTUC cadence to the whole approved list at once below.
LinkedIn 1st–10th every month · Google RSA 5th–25th every month · Aug 2026 → Mar 2027. Existing per-ad budget overrides are kept — only flight dates are (re)set.
CPL targets (uPLAY plan)
9-month action media plan leads funnel journey, month by month
One theme in primary focus per month (seasonal themes get their declared peak window, the rest rotate through), what's actually built for it, the lead magnet it offers, the retargeting move that month, and planned spend — a single action sheet instead of six separate tabs.
Retarget action follows calendar time-in-market, not theme — the pixel's retarget pool only gets warmer the longer the campaign runs, regardless of which theme is in focus that month.
Audience Matrix
Toggle chips to include/exclude segments. Selections flow into the export.
LinkedIn — job titles
Industries
Company size
Geo
LinkedIn funnel audiences
Google — intent capture
Best practice (2026, cited in plan): 3–4 form fields — adding phone drops completion 15–20%. Keep phone optional if volume lags.
The Flywheel — How Every Ad Copy Connects
Google and LinkedIn are not two separate campaigns — they're two stages of one flywheel. Google captures people who are already searching (Decision); LinkedIn builds the audience who isn't searching yet (Discovery) and brings back the ones who didn't convert (Consideration). This page shows where every current ad sits in that loop, so picking the next ad copy is a placement decision, not a guess.
The flywheel for
Each stage feeds the next; Google SEO / brand search feeds back into stage 1 — every qualified lead and every piece of thought-leadership content compounds, so cost-per-lead should fall over the 9 months rather than stay flat.
Connected 9-month media plan actual scheduled ads, by funnel stage
Same flights as Schedule, split by stage instead of theme — this is the view that shows whether Discovery/Consideration content is actually running *ahead of* the Decision-stage push each month, the way the flywheel needs it to.
Competitive & Trend Research
Live internet research via Claude AI with web search — top-ranking ads and keywords, and trending category content, always benchmarked against competitors of uplaybusiness.com.sg. Findings are cited and must be verified before entering the keyword plan or ad copy.
All four buttons keep you on this page — results (or, for the free engines, the prompt to paste) always land in the Findings box on the right, never a new tab.
Top 10 trending results in Google for this focus, with the ad angles/keywords already ranking.
What's rising on Google Search right now for this focus, summarised with citations.
Top keywords or ads currently running in Google, broken down by competitor.
5 ranked hook lines for the funnel stage, segment and theme selected above.
Manual research consoles
↗ LinkedIn Ad Library — search competitor company pages
↗ Meta Ad Library (SG)
↗ Google Trends — Singapore
Findings 0 saved
Keyword Plan — Verified Research
Grouped by ad theme — shaped by HR audience interest and buyer intent. SG volumes from the approved keyword workbook (UPlay_for_Business__Content_Calendar__Keywords__Questions.xlsx). Tick to include in the Google build.
🚫 Negative keywords Google RSA
Applied at the Google Ads campaign level for — excludes searches this account should never show for (job-seekers, bargain hunters, off-brand terms). Not sourced from the keyword workbook — set and maintained here, validate in Google Ads before launch.
Paste keywords to select
Paste or type a list of keywords (one per line, or comma-separated). Anything already in the list gets ticked; anything new gets classified into a theme, added, and ticked — no duplicates on repeat pastes.
✦ Generate keyword ideas (AI)
How to use: pick an AI engine below, then click Generate. Claude/Gemini run live and add ideas automatically. ChatGPT/Copilot (free) copy the prompt to your clipboard instead — paste it into the tool yourself, paste its reply back into the box that appears, then click "Apply pasted reply."
Saved keyword groups
Save the currently-ticked keywords as a named set (e.g. "Group 1") so you can recall or re-select that exact combination later — separate from theme grouping.
Content Ad Generation — Approval-Ready Previews
Pick a format, edit text live, load an image or generate copy + an image brief with AI. Save each ad into the Approval library.
Manual / regenerate individually
Preview approximates live placement. LinkedIn single image 1200×627 · carousel 1080×1080 · brand: -135° yellow→red gradient, logo top-left, rounded shape motif, 60/40 image-to-content.
Content Approval Board
Every launch creative for the selected brand is preloaded with its full visual — uPLAY: 30 ads · D'Marquee: 30 ads, rebuilt against the current theme groups (regrouped 2026-09-03). Sorted by latest activity (most recently saved/edited first) with each ad's theme group shown on its card — click the status or channel tiles above the list to filter.
- ✎ Edit — opens the ad in Ad Studio. Saving there overwrites this ad copy directly.
- Mark Approved — a UTM-tagged Final URL appears on the card automatically, ready to copy into the ad platform for tracking.
- 📅 Schedule — set flight dates and budget; it flows straight into the Calendar.
- 🚀 Launch steps (in the Calendar) — exact, platform-specific steps to build that ad in Google Ads or LinkedIn.
- Status flow: Draft → Review → Approved → Scheduled → Live → Ended.
- Deleted ads move to Trash (hidden by default, never exported) until a Super Admin empties it.
📡 Landing page & GTM setup required before launch — read this once per brand (applies identically to UPlay and D'Marquee)
Every tagged URL on this board only works end-to-end if the brand's own website is set up to receive it. This is the same checklist for both uplaybusiness.com.sg and dmarquee.com.sg — only the GA4 property and LinkedIn Insight Tag Partner ID differ per brand.
- 1 · Install GTM on both pages. The same Google Tag Manager container (GTM-MTSNJ2FC for UPlay; confirm D'Marquee's own container ID) must be present on the landing page (the contact-us page ads point to) and the thank-you page shown after form submit — not just one of them.
- 2 · Capture the UTMs on landing. Add GTM URL Query variables for utm_source, utm_medium, utm_campaign, utm_content, utm_term, utm_id and write them to a first-party cookie or sessionStorage on page load — the visitor may browse before submitting the form, so the UTM off the ad click must survive to whenever they convert.
- 3 · Carry them to the thank-you page. On the thank-you page, read that stored UTM set back out and push it into the dataLayer before the generate_lead event fires, so GA4 attributes the lead to the exact theme/ad/keyword — not just "direct."
- 4 · Leave platform auto-tagging ON. Google Ads' own gclid and LinkedIn's li_fat_id are separate click IDs the platforms add automatically — do not disable Google Ads auto-tagging because manual UTMs are also in use. Both are meant to run side by side (gclid/li_fat_id feed the platforms' own attribution; UTMs feed GA4, the CRM and any BI tooling outside the ad platforms).
- 5 · Google's {keyword} is expected to look "unfilled." It's a live Google Ads ValueTrack macro, not a placeholder bug — Google Ads substitutes it with the actual matched search term the moment the ad serves. It only resolves inside a real Google Ads account, never in a browser address bar.
- 6 · QA once before spending real budget. Copy one tagged URL from a card below, open it, submit a test lead, and confirm in GA4 DebugView that the generate_lead event on the thank-you page carries the correct source/medium/campaign/content/term. Repeat for both brands — each has its own GA4 property.
Full step-by-step GTM/GA4 wiring lives in Conversion & Tags — this box is the short version aimed at whoever owns the brand's website.
Content Calendar — Final Approved Ads
Every ad that reaches Approved status on the Approval board appears here automatically with its flight dates. Click 🚀 Launch steps on any row for the exact, platform-specific steps to build that ad in Google Ads or LinkedIn Campaign Manager — including its UTM-tagged Final/Destination URL. This section is view-only for Team users — only a Super Admin can change flights or status (via the Approval section, or by dragging cards on the Kanban board below), so the calendar always reflects the approved plan.
Flight approved ads across the nine months
Approved assets appear here by month and theme. Use the Kanban to track production; drag cards to update status. Each month totals its flight spend.
Flighting board — Google vs LinkedIn visual timeline · Jul 2026 – Mar 2027
Part 1 · Confirmed events name · date/window · theme
The confirmed, scheduled events this campaign is built around — e.g. HR Connect 2026. Add each event with its name, confirmed date/window and the theme it carries.
Performance & Funnel — Live Inputs Only
Planned spend is pulled from the Media Plan & Budget section. Actuals stay empty until real platform data is entered — CTR, CPL, pacing variance and funnel conversions compute automatically. No performance figures are pre-filled.
🔒 Governance — Optimisation Trigger Guide Super Admin only
The exact thresholds the recommendations above are computed from — not separate policy, this documents what the code already does, so it stays auditable when a Team member asks "why did it say pause this?"
| Signal | Trigger | Action |
|---|---|---|
| Keyword CPA | > 1.5× the phase CPL target | Pause the keyword or reduce its bid |
| Keyword CPA | Best-performing keyword this cycle | Raise bids/budget on it to capture more volume |
| Overall CPL | Above the phase target (<$110 Ramp · <$80→<$65 Scale · <$75 Optimise) | Shift budget to the strongest theme, or pause its weakest ad groups |
| Overall CPL | At or below the phase target | Hold allocation; test incremental budget on the top theme |
| Spend pacing | > 110% of plan-to-date | Cap spend or re-check bids before month-end |
| Spend pacing | < 70% of plan-to-date | Accelerate spend on the best-performing theme |
Source: mediaRecommendations() and cplTarget() — CPL targets come from the approved NTUC media plan phases (Ramp/Scale/Optimise), not an estimate.
Data source
How to connect Google Ads API → this dashboard
- 1 · Google Ads (manager/MCC account) → Tools → API Center → apply for a Developer Token (Basic access is enough for own accounts).
- 2 · Google Cloud Console → new project → enable Google Ads API → OAuth consent screen (internal) → create OAuth 2.0 Client ID (Web application).
- 3 · Generate a refresh token for the account email that can read the UPlay ads account (OAuth playground or the google-ads client library helper).
- 4 · Deploy this dashboard on Netlify (or Hostinger + a small Node service) and add serverless function netlify/functions/google-ads-report.js holding: developer token, client ID/secret, refresh token, customer ID — as environment variables, never in this HTML.
- 5 · The function runs a GAQL query, e.g. SELECT segments.month, metrics.cost_micros, metrics.impressions, metrics.clicks, metrics.conversions FROM campaign WHERE segments.date DURING LAST_30_DAYS (and the keyword_view query in the keyword card) and returns JSON.
- 6 · The 🔗 button then fetches /.netlify/functions/google-ads-report and fills Actual spend / Impr. / Clicks / Leads per month — real data only.
How to connect LinkedIn Ads API → this dashboard
- 1 · LinkedIn Developer portal → create an app tied to the NTUC Club/UPlay company page → request the Advertising API product (Marketing Developer Platform approval, typically a few days).
- 2 · OAuth 2.0: scopes r_ads, r_ads_reporting → obtain access + refresh tokens for a user with viewer access to the ad account.
- 3 · Serverless function linkedin-report.js calls GET /rest/adAnalytics?q=analytics&dateRange=…&timeGranularity=MONTHLY&accounts=urn:li:sponsoredAccount:{id}&fields=impressions,clicks,costInLocalCurrency,oneClickLeads.
- 4 · Lead Gen Form leads: oneClickLeads in analytics, or export via Lead Sync to Salesforce (Kathleen's routing) — the dashboard reads the analytics numbers.
- 5 · Same env-variable rule: credentials live server-side only. Until then this stays NOT CONNECTED and manual.
Topline Summary
Clean topline read of spend/performance and the lead funnel. Spend/Impr./Clicks/CTR/CPL recompute for the selected theme or ad group; funnel-stage totals (below) are campaign-wide.
Performance by Funnel Stage where's the budget actually working?
Same ads as Content Journey's Discovery/Consideration/Decision lanes, rolled up by performance instead of by count — this is the view for deciding whether to shift budget toward what's converting.
Monthly performance input
Performance by theme · ad group manual inputs · computed metrics
Pick a theme or ad group to see its performance — nothing renders until you select one, to keep this section short.
Keyword performance rank by any metric
Pick a theme to see its keyword performance — nothing renders until you select one, to keep this section short.
How to read keyword performance from Google Ads
- Where: Campaigns → Audiences, keywords & content → Search keywords. Add columns: Impr., Clicks, CTR, Avg. CPC, Conversions, Cost/conv., Conv. rate, Search impr. share, Quality Score (Ad relevance · Expected CTR · Landing page exp.).
- What "best" means here: primary = Conversions & Cost/conv. vs the phase CPL target (Ramp <$110 → Scale <$80 → Optimise <$75); secondary = CTR ≥ ad-group average and QS ≥ 6; volume check = Search impression share (low share + good CPA → raise bids/budget).
- Decisions: scale winners (high conv, CPA under target), fix middle (good CTR, no conv → landing page/form), pause losers (spend > ~2× target CPA with 0 conv after learning), and mine the Search terms report weekly for new keywords + negatives.
- API pull (GAQL): SELECT campaign.name, ad_group.name, ad_group_criterion.keyword.text, metrics.impressions, metrics.clicks, metrics.ctr, metrics.conversions, metrics.cost_micros FROM keyword_view WHERE segments.date DURING LAST_30_DAYS
Primary integration — click-to-lead tracking (GA4 + GTM) must be live before launch
Every click must be attributable to a lead in GA4, or the CPL ladder and keyword decisions above have no ground truth. Container on file: GTM-MTSNJ2FC.
Implementation checklist (Tag Manager)
- 1 · GA4 base: in GTM add a Google Tag with the GA4 Measurement ID (G-XXXX), trigger All Pages, on uplaybusiness.com.sg. Verify in GA4 Realtime.
- 2 · Lead event: GA4 Event tag generate_lead; trigger = form submit on /contact-us (Form Submission trigger or Thank-You page view — prefer thank-you URL for reliability). Add params: form_id, product_interest.
- 3 · Mark as key event: GA4 Admin → Events → toggle generate_lead as a Key event (conversion).
- 4 · Google Ads: link GA4 ↔ Google Ads (Admin → Product links), import the generate_lead key event as a conversion, set it as primary for bidding (Max Conversions → tCPA).
- 5 · LinkedIn: add the LinkedIn Insight Tag (via GTM Community template) + a conversion rule on the thank-you URL; Lead Gen Form leads report natively in Campaign Manager and must be exported/CRM-synced to Salesforce (Kathleen Wong routing).
- 6 · UTMs: every Final URL carries utm_source=google|linkedin&utm_medium=cpc|paid_social&utm_campaign=[theme]&utm_content=[ad id]&utm_term=[keyword|cta]&utm_id=[theme] — matches the naming convention so GA4 reports slice by theme/ad/keyword. The landing page must read these from the URL (via a GTM URL variable or first-party cookie) and carry them through to the thank-you page's dataLayer so the generate_lead event still has them.
- 7 · QA: GTM Preview + GA4 DebugView on a test submission before 15 Jul; confirm the lead lands in Salesforce with source captured.
Lead funnel
Route: Lead Gen Form / landing form → Salesforce. MQL/SQL definitions to be agreed with Kathleen Wong.
Monthly optimisation cadence
Export Any Section
Select sections and print to PDF as landscape proposal slides, download the media plan as CSV for Excel, or save the full state as JSON for team handoff.
Slide export (Print → Save as PDF, landscape)
If Approval is ticked, the slides always include Review and Approved ad copy only — Draft, Scheduled, Live, Ended and Trash are left out automatically, regardless of whatever filter is currently set on the Approval page.
Data exports
The ad copy handoff workbook includes only Review and Approved ad copy — one sheet per channel, every headline/description/card in its own column, a Comments column with the full review thread, and a clickable link in the Image column for any ad sourced from the image library (locally uploaded images are noted instead, since they're not a file path).
The companion PowerPoint proposal deck (UPlay-branded) is generated separately by AKA Digital and mirrors this dashboard's confirmed content.
🌐 Host at akadigital.net/reach (Hostinger)
Connection steps
- 1 · Log in to hpanel.hostinger.com → Websites → akadigital.net → Dashboard.
- 2 · Open File Manager (or connect FTP: Files → FTP Accounts) → navigate to public_html/.
- 3 · Create folder reach → upload this file into it → rename to index.html.
- 4 · Visit akadigital.net/reach — live immediately (SSL already covers the main domain path).
- 5 · Keep it private: hPanel → Advanced → Password Protect Directories → select /public_html/reach → set a username/password. Visitors then need this server-level login before the page loads — real access control, stronger than the in-app view/edit lock (which governs editing rights after entry).
- 6 · Optional subdomain instead: hPanel → Domains → Subdomains → create reach.akadigital.net pointing to the same folder.
- 7 · Updates: re-upload index.html to overwrite. Note: each visitor's campaign data does NOT live on Hostinger — see the storage card below.
💾 Where campaign data is stored — and how to manage access
All edits (ads, keywords, schedules, performance inputs, research notes — both brands) are saved in the browser's localStorage on each user's own device, under the key uplay_cb4. Nothing is sent to or stored on Hostinger, AKA Digital, or any server.
What this means + advice
- Per-device, per-browser: Veronica's Chrome and Jeffrey's Chrome each hold their own copy. Hosting on akadigital.net/reach shares the tool, not the data.
- Single source of truth: nominate one owner for edits. Everyone else opens the page view-only (default lock) so no conflicting local copies build up.
- Team sync = JSON handoff: owner clicks 💾 Save JSON or 📋 Copy JSON → commit the generated file to your GitHub repo as uplay_campaign_builder_state.json and use it as the canonical shared state.
- Backups: export JSON after each working session — clearing browser data, incognito mode, or a different device means an empty dashboard.
- Sensitive data note: keep client performance figures out of shared JSONs sent externally; the file is plain text.
- True multi-user storage (shared live database, roles, audit trail) requires the Netlify/backend build — same move that unlocks real API pulls and server-side auth. Recommended once the campaign is live.
Wire the lead tracking — UTM, GTM & tags, step by step
Written for someone doing this for the first time. Follow the 6 steps top to bottom and tick each one off. When all 6 are green, every Google Ads and LinkedIn Ads click can be traced in the brand's GA4 to the exact campaign, theme and ad that produced the lead — on the landing page and the thank-you page.
Auto-generated UTM final URLs GTM & gclid compliant
Every approved ad is tagged automatically the moment it's marked Approved or later — for both Google Ads and LinkedIn Ads, using the naming rules below. This is the default and recommended path: it can't drift from the ad's actual theme/id the way typing a URL by hand can. gclid (Google) and li_fat_id (LinkedIn) auto-tagging are untouched — these UTMs run alongside them, not instead of them; capture them in GTM as URL Query variables (utm_source, utm_medium, utm_campaign, utm_content, utm_term, utm_id) per step 2 below. Copy each tagged URL into the ad platform as the Final URL / Destination when building the live campaign.
UTM URL builder manual override
Only for a link with no saved ad behind it (e.g. a newsletter or organic-social link) — anything running as a Google or LinkedIn ad should use the auto-generated table above instead, so it can never drift from the ad's real theme/id.
Naming rules for this campaign
Keep these exact spellings — GA4 treats "Google" and "google" as two different sources. Lowercase everything, use underscores, never spaces. Google's {keyword} is a live ValueTrack macro — it looks unresolved until the ad is actually serving inside Google Ads; that's expected, not a bug. Manual UTMs never replace Google's own gclid or LinkedIn's li_fat_id auto-tagging — both run side by side.