/* Page: Single client SEO Overview */ function OverviewView({ client, range }) { const rangeParam = range === 'Last 7 days' ? '7d' : range === 'Last 90 days' ? '90d' : range === 'YTD' ? 'ytd' : '30d'; const { data: D, loading, error } = useApi( `/api/clients/${client.id}/overview?range=${rangeParam}`, [client.id, rangeParam] ); if (loading) return
Loading overview...
; if (error) return
Failed to load overview: {error}
; const traffic90 = D.traffic90 || []; const trafficPrev = D.trafficPrev || []; const totalSessions = traffic90.reduce((a,b) => a+b, 0); const prevSessions = trafficPrev.reduce((a,b) => a+b, 0); const delta = prevSessions > 0 ? ((totalSessions - prevSessions) / prevSessions) * 100 : 0; return ( <>
SEO · Q2 2026 in progress

Foundation set. Rank stabilising. Content investment unblocked.

Cannibalisation resolved on 3 priority clusters. Crawl budget recovered. Organic sessions +18% MoM in March.
Organic sessions {(totalSessions/1000).toFixed(1)}k +{delta.toFixed(1)}% vs prev 90d GA4 · last 90 days
Conversions {D.conversions} +{D.convDelta}% GA4 · key events
Avg position {D.avgPosition} −2.7 GSC · 142 tracked
CTR {D.ctr}% +0.6pp GSC · last 28 days
Top-3 keywords {D.top3Keywords} +11 Semrush · tracked set

Organic traffic

Daily sessions · 90 days
Sessions Users Engaged
Current 90d
{totalSessions.toLocaleString()}
Previous 90d
{prevSessions.toLocaleString()}
Best day
{(traffic90.length ? Math.max(...traffic90) : 0).toLocaleString()}
GA4 · property 287654032Synced 14m ago

Top movers

Last 7 days
Climbing
{(D.topMovers?.up || []).map((m, i) => (
{m.kw}
{m.page}
{m.from} {m.to}
))}
Slipping
{(D.topMovers?.down || []).map((m, i) => (
{m.kw}
{m.page}
{m.from} {m.to}
))}

Channel mix

GA4 · 30d
a + c.value, 0)}/>
{(D.channels || []).map((c, i) => (
{c.name} {c.share.toFixed(1)}%
))}

This cycle's findings

{[ { p: 'High', t: 'Cannibalisation across 14 pages', d: 'Core service terms split rank between competing pages. Highest-leverage fix this cycle.' }, { p: 'High', t: '340 parameterised URLs wasting crawl budget', d: 'Faceted-nav URLs indexed without intent. Block in robots.txt.' }, { p: 'Med', t: 'Cluster architecture missing for 3 service lines', d: 'No pillar pages anchor mid-funnel intent. Briefs queued for Q2 execution.' }, ].map((f, i) => (
{f.p}
{f.t}
{f.d}
))}

Data sources

Last sync
{(D.dataSources || []).map((s, i) => (
{s.name.toUpperCase()}
{s.prop}
STATUS {s.status.toUpperCase()}
))}
); } window.OverviewView = OverviewView;