Content ROI attribution: join GSC and GA4 by landing page
How to join Google Search Console and GA4 by landing page URL, assign lead value with no revenue event yet, and stop last-click from hiding organic's real ROI.
How to join Google Search Console and GA4 by landing page URL, assign lead value with no revenue event yet, and stop last-click from hiding organic's real ROI.

Most SaaS teams already have Google Search Console and GA4 running, side by side, on the same domain, for months. Ask "is the blog making money" and you still get a shrug, because nobody ever joined the two datasets on the one field they share: the landing page URL. This is the join, the value formula for when you don't have a real revenue event yet, and the attribution trap that undercounts organic content on every last-click report you've ever pulled.
If you're earlier in the process and still deciding whether a blog is worth the investment at all, start with SEO for SaaS; this post picks up after you've published and need to prove the return.
Post counts and traffic charts describe activity. ROI describes an outcome: dollars in against dollars, or a credible proxy for dollars, out. A post count tells you what you shipped. It says nothing about whether any of it moved a lead, a trial, or a renewal.
The reason most teams stop at activity metrics is that the two systems that hold the real answer don't talk to each other by default. Search Console has your organic clicks, impressions, and queries per URL. GA4 has your conversions, revenue, and assisted paths per URL. Neither tool natively serves both halves of that sentence at once. So teams report the half they have (traffic) and skip the half they don't (what the traffic was worth), and "content ROI" quietly becomes "content volume" with a nicer name.
Fixing that isn't a dashboard purchase, it's a join. Landing page URL is the field both datasets already track, and once you line it up, you can put organic clicks on one side of a row and conversions or lead value on the other. That's the rest of this post, and it's the same discipline Lyra runs before she recommends what to write next: an autonomous writer is only as good as the ROI signal deciding what it should tackle.
The direct answer: join GSC and GA4 on landing page URL, normalized to match, then read organic performance and conversion outcomes off the same row. Nothing else both tools track natively lines up cleanly enough to build a join key from.
Search Console reports clicks, impressions, average position, and the actual queries that earned them, all indexed by page. GA4 reports sessions, conversions, revenue, and multi-step user paths, also indexed by page, but as a landing page dimension rather than a query dimension. Neither tool knows what the other tracks. GSC has no concept of a conversion event; GA4 has no concept of a search query's position. Landing page URL is the one dimension that exists, cleanly, on both sides, which makes it the natural join key for tying organic discovery to what happened after the click.
Here's where the join breaks if you skip it: GSC returns full URLs (https://example.com/blog/post-slug/) while GA4 returns paths only (/blog/post-slug/). Join them as-is and every row mismatches. Before blending, strip the protocol and domain from the GSC side, trim trailing slashes consistently on both sides, strip tracking query parameters, and lowercase device and country fields, since GSC and GA4 don't format those the same way either. Sort this out first; a join key that looks fine at a glance but mismatches on case or a trailing slash will silently exclude rows instead of erroring.
Pick based on your data volume and who's maintaining the report:
FULL OUTER JOIN on the normalized URL so pages with clicks but no conversions, and pages with conversions but no organic clicks, both still show up instead of silently dropping out of an inner join.One clarification worth making explicit: linking a GSC property inside GA4 (Admin, then Product links, then Search Console Links, which requires you to be an Editor on the GA4 property and the same verified email as a GSC owner) is not the same as joining the data. Linking only surfaces GSC tiles inside GA4's Acquisition reports; it doesn't produce a blended table you can build a dashboard on. You still need one of the three methods above for a real landing-page-level join.
Once you have clicks and conversions on the same row, the next question is what a conversion is actually worth. That answer depends entirely on whether you have a real revenue event yet.
If your blog drives demo requests or trial signups rather than direct purchases, the direct answer is: Estimated Lead Value equals average customer lifetime value multiplied by lead-to-customer close rate. A $10,000 average LTV at a 5% close rate assigns $500 to every qualifying lead event.
You set that number as the value parameter (with a currency) on the key event itself, not on the conversion label: in Admin, under Data display, open Events, find the event on the Key events tab, and set its default key event value. Every landing page that generates that event then rolls its leads up into a dollar total automatically, giving you a defensible per-page revenue estimate long before a deal actually closes.
Here's the mechanics end to end, walked through on one landing page with placeholder figures so the arithmetic is concrete before you touch your own data. GSC reports 340 organic clicks and 12,400 impressions over the trailing 90 days on a given post. You normalize the URL, pull the matching GA4 row for that same path, and find 6 demo-request conversions logged against it in the same window. At a $10,000 LTV and a 5% close rate, that single row is worth 6 x $500, or $3,000 in estimated lead value, against whatever the post cost to write and keep current. Run that same row for every post on the site and the ranked list falls out on its own, which is the output a post count could never give you.
If your product has a self-serve checkout or you can stitch CRM close data back into GA4, use the real number. It's more accurate and it survives an audit. Estimated Lead Value is the fallback for the far more common SaaS case: a multi-week or multi-month sales cycle where the conversion GA4 sees (a demo request, a signup) happens long before the revenue event does, if it happens at all. Treat the estimate as a placeholder, note it as an estimate wherever you report it, and swap in real revenue the moment your sales cycle produces it.
Content sits earlier in most B2B buying journeys than the touch that gets credited. A reader finds you through a blog post that answers a specific question, doesn't convert that visit, and comes back three weeks later through a branded search or a direct visit to sign up. Last-click attribution hands 100% of the credit to that final touch and zero to the post that started the journey, which makes organic content look worse than it performed.
GA4 does have a model built to fix this: data-driven attribution, which distributes conversion credit across the touchpoints in a path instead of handing it all to the last click. Google's own documentation confirms the model draws on your account's actual conversion data but doesn't publish the exact volume it needs before it kicks in. 1ClickReport's attribution guide puts the practical bar at roughly 400 conversions on the specific key event you're analyzing and 20,000 qualifying conversions across the account within the lookback window, based on their work auditing GA4 properties. Most early and mid-stage SaaS properties never clear that bar on their primary conversion event.
Below that threshold, GA4 doesn't warn you in the interface, it quietly runs on last-click attribution while the setting still reads "data-driven." Seresa's attribution research describes the same silent fallback independently: "GA4 doesn't show an error. It doesn't display a warning." If you're a smaller property reading a report that says data-driven attribution and assuming it's crediting the full path, treat that assumption as unverified and cross-check your actual conversion volume before you trust it.
GA4's newer Conversion Attribution Analysis report (currently in beta) adds an Assisted Conversions view that surfaces the upper-funnel touchpoints last-click hides, alongside a Refined Funnel Analysis view that buckets touchpoints into Early, Mid, and Late stages of the path. Even without hitting the data-driven volume threshold, pulling up the assisted-conversions view for your top organic landing pages will show you which posts are opening journeys that later close somewhere else, instead of writing them off as zero-value because they never carried the final click.
Build one table, one row per landing page, with these columns:
| Column | Source | Notes |
|---|---|---|
| Landing page URL | GSC (normalized) | Join key; strip protocol, domain, trailing slash, query params |
| Organic clicks | GSC | Last 28 or 90 days |
| Organic impressions | GSC | Watch this against clicks for pages ranking but not earning clicks |
| Conversions | GA4 | Key event(s) you've configured, e.g. demo request, signup |
| Estimated or real value | GA4 | Estimated Lead Value or actual revenue per the formula above |
| Assisted conversions | GA4 (Conversion Attribution Analysis, beta) | Credit the page picks up as an earlier touchpoint |
Build it as a Looker Studio blend if you want it live and shareable, or a spreadsheet if you're validating the approach before automating it. Either way, the output is the same: a ranked list of which posts are actually worth their production cost, not just which ones got published. If you're weighing where new topics should go next, topic cluster strategy already frames prioritization in ROI terms, ranking gaps by which one is the highest-ROI post to write first; this dashboard is what tells you whether that bet paid off after the fact.
A post with rising GSC impressions and flat GA4 conversions is telling you it's found its audience but hasn't earned the click, or it's earned the click but not the action. Check impressions against clicks first: if clicks are flat while impressions climb, the title and meta description aren't earning the click that's already available, which is a faster fix than a content rewrite. If clicks are healthy but conversions are flat, look at whether the page actually points anywhere: a post that never mentions a next step won't convert no matter how much organic traffic it earns, which is where deliberate internal linking into your product or contact pages closes the gap instead of leaving the reader stranded at the end of the article.
If impressions and clicks are both present but sliding over time on a post that used to convert, that's a decay signal, and the fix is a scheduled rewrite rather than a guess: our content refresh strategy covers detecting that decay in Search Console and shipping the refresh as a quarterly pull request. Either way, the dashboard above is what tells you which failure mode you're actually looking at, instead of guessing from a traffic graph alone.
We went through the earlier version of this problem ourselves, publishing without any way to tell which posts were paying for themselves, a gap we describe in why we built Lyra. This dashboard is the revenue side of the ledger. The cost side has two separate line items: what it costs to write a post, covered in Claude API cost per blog post, and what it costs to run the keyword research that feeds your topic pipeline in the first place, which DataForSEO vs Ahrefs vs Semrush prices out separately since the three tools charge for that very differently.
Joining GSC and GA4 tells you which posts are earning their keep. Lyra writes the next ones with that same landing page in mind, verified and shipped as a pull request you review before anything goes live.
FAQ
On landing page URL, which is the only dimension both tools share. GSC returns full URLs and GA4 returns paths, so you strip the protocol and domain from GSC's URL, trim trailing slashes and query params from both sides, and lowercase device and country values before you blend or join them in Looker Studio, a spreadsheet, or BigQuery.
No. The Admin > Product Links > Search Console Links setting only surfaces GSC data as extra tiles inside GA4's Acquisition reports. It does not blend the two datasets or let you build a single table with organic clicks next to conversions per URL. For that you still need a Looker Studio blend, a spreadsheet lookup, or a BigQuery export.
Assign an Estimated Lead Value to your conversion event: average customer lifetime value multiplied by your lead-to-customer close rate. A $10,000 LTV at a 5% close rate values each qualifying lead at $500, which you set as the event's value parameter in GA4 so every landing page's leads roll up into a dollar figure.
Because last-click attribution credits the final touchpoint only, and content usually sits earlier in the path. GA4's data-driven model is built to spread credit across the journey instead, but per 1ClickReport's 2026 GA4 attribution guide, it needs roughly 400 conversions on the specific key event and 20,000 qualifying conversions account-wide before it activates, a bar most SaaS properties never clear, so the report quietly reverts to last-click while the setting still reads data-driven, a fallback Seresa's attribution research describes the same way: no warning, no error, just a silent switch.
Built by the tool you're reading about
Lyra finds the topics worth ranking for, writes them in your repo's voice, fact-checks every claim, and opens a pull request scored and ready to merge. You review and hit merge. Want to see what she'd write for you? Tell us about your blog and the founder will walk through it with you.
Keep reading

A Notion to git blog migration playbook: where Notion breaks down as a CMS for SEO, how to map redirects, and how to move without losing rankings.

Solo founder content marketing without a writer or agency: how much time it really costs, what only the founder can do, and a weekly schedule that holds.

Changelog SEO means giving each release note its own URL, a descriptive slug, and TechArticle schema so it ranks, instead of one long unindexable feed.