You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Turn HitKeep's existing Google Search Console settings page and dashboard drilldown into one polished, site-scoped Search Performance workspace for SEO, content, and growth work.
The workspace should combine accurate imported Google Search metrics, previous-period comparisons, Search Appearance reporting, and page-level HitKeep outcomes, while making connection setup, property mapping, sync health, and recovery much clearer.
Problem
The current Search Console surface is useful but fragmented:
Connection and property mapping live in a settings-oriented integration page, while reporting is tucked into an oversized dashboard drilldown.
The report is shallow: fixed-size results, limited comparison and filtering, no Search Appearance view, and no page-level outcome context from HitKeep.
Headline totals and dimension rows are derived from combined query shapes, which makes aggregation semantics harder to understand and can reduce accuracy.
Loading and failure behavior is too coarse. A failed request can obscure otherwise usable data, and sync problems do not always lead users to a clear recovery action.
Healthy connection states still expose setup-oriented or disabled controls, adding noise.
The current surface does not scale well for a serious search-performance workflow.
Who Benefits
Site owners diagnosing organic-search performance
SEO and content teams prioritizing queries and landing pages
Growth teams connecting search visibility to on-site outcomes
Operators troubleshooting OAuth, property access, mapping, and imports
Self-hosted and HitKeep Cloud users equally
Proposed Solution
1. Create a dedicated Search Performance workspace
Add a site-scoped /search-console route under Analytics for every authenticated site viewer.
Remove the duplicate Integration navigation item. Redirect the old /integration/google-search-console route to /search-console?tab=connection, and return OAuth callbacks there.
The Performance tab should include:
The shared date-range toolbar
An equal-length previous-period comparison
Four selectable KPI metrics: clicks, impressions, CTR, and average position
One restrained trend chart
Server-paginated tables for Queries, Pages, Countries, Devices, and Search Appearance
Default sorting by clicks descending
Page sizes of 25, 50, and 100
Reversible query/page contains filters and exact country/device filters
A compact KPI/trend summary on the main dashboard with an Open Search Console action, replacing the current large drilldown
Search Appearance should be a date-range/comparison table only. It should not be combined with the other dimension filters because the Search Analytics API's aggregation behavior can otherwise produce misleading totals.
2. Add page-level HitKeep outcome context
For each Search Console page row, show same-period HitKeep context derived from the normalized landing-page path:
Tracked landing sessions
Bounce rate
Goal conversions
Previous-period comparison for the same measures
Clearly label this as outcomes for all HitKeep-tracked traffic landing on that page. Do not present it as Google-attributed traffic or imply causality.
3. Deepen and harden the imported data model
Version search_console_facts with a dataset discriminator and search_appearance support.
Import finalized Web Search data into seven datasets:
Property totals
Queries
Pages
Countries
Devices
Search Appearance
Existing combined dimensions used for cross-filtering
Use:
Property totals for accurate headline metrics
Dimension-specific datasets for unfiltered tables
Combined dimensions only when query, page, country, or device filters require them
During a 90-day v2 backfill:
Preserve legacy facts until the replacement dataset succeeds
Switch reporting atomically to the new model
Remove legacy rows for the mapped site/property only after successful cutover
Transactionally replace each rolling date window so rows that disappeared upstream do not remain stale
Retain the last good dataset when refresh fails
Store only a safe, actionable error category
After a property is mapped, request the initial sync automatically. While the page is visible, poll sync status every five seconds and stop when the state is stable or after two minutes.
Include Search Console facts in site/user takeout as search_console_fact. Never export OAuth tokens, credentials, provider headers, or raw provider error bodies.
4. Make connection and recovery states clear
The Connection tab should show a compact status summary and one contextual primary action. Avoid healthy-but-disabled setup controls. Separate destructive actions visually and explain their scope.
Load status, overview, chart, and active table independently so one failed section does not blank the rest of the workspace.
Support localized, actionable states for:
No site selected
Missing server credentials
Disconnected account
Unmapped property
No compatible property
Initial import
Empty result
Partial date range
Quota exhaustion
Google service outage
Revoked authorization
Token refresh failure
Property access loss
Permission denial
Generic safe failure
Use skeletons for first load and retain visible data during refresh. Keep last-good reporting available during failed or attention-required syncs, with the relevant recovery action.
Hide mutation controls from read-only users instead of showing disabled controls.
A valid OAuth callback should redirect with a safe success/error code. Invalid or mismatched state should remain an HTTP error and must not expose provider response bodies.
Disconnect copy must explain that every team site mapped through that connection will stop syncing while previously imported data remains. Removing a mapping affects only the current site.
5. Extend the public reporting surface additively
Keep existing routes and response fields backward compatible while adding:
Paired compare_from / compare_to
query_contains
page_contains
offset
sort
direction
dimension=search_appearance
Comparison metrics on overview, series, and dimension rows
total, limit, offset, and has_more on dimension responses
Optional current/comparison hitkeep_context on page rows
Stable warning codes for partial ranges, legacy backfill, sync failure/attention, and anonymized-query limitations
Import-model version in sync status
Extend the read-only aggregate MCP tool hitkeep_get_search_console with Search Appearance reporting. Update MCP audit expectations and public analytics procedures.
Update both the runtime OpenAPI source and the docs OpenAPI copy.
User Workflow
A site viewer opens Analytics → Search Console.
If setup is incomplete, the workspace explains the exact state and presents the next valid action.
After property mapping, HitKeep starts the initial import automatically and updates visible status until it settles.
The viewer compares clicks, impressions, CTR, and position across periods, then explores paginated query, page, country, device, or Search Appearance results.
On the Pages tab, the viewer can relate search visibility to clearly labeled, non-attributed HitKeep landing outcomes.
If Google sync later needs attention, the last good report remains available and the Connection tab provides a safe recovery path.
Success Criteria
A dedicated responsive Search Console workspace replaces the fragmented settings/drilldown experience.
Performance and Connection tabs are deep-linkable and the legacy integration route redirects safely.
Headline totals use property-level imports rather than sums from combined dimensions.
Queries, Pages, Countries, Devices, and Search Appearance support server pagination and comparison.
Query/page contains filters and exact country/device filters are reversible and URL-safe.
Search Appearance is reported without unsafe cross-dimension aggregation.
Page rows show clearly disclaimed HitKeep landing sessions, bounce rate, and goal conversions for current and comparison periods.
Initial sync starts automatically after mapping.
Legacy data remains readable until a successful atomic v2 cutover.
Rolling-window replacement removes stale upstream rows without exposing partial imports.
Section-level failures preserve unaffected and last-good data.
Every known setup, empty, partial, quota, authorization, access, and outage state has localized copy and a relevant action.
Read-only users can view reports without seeing mutation controls.
Disconnect and unmap actions clearly communicate their different scopes.
API additions are backward compatible and documented in both OpenAPI sources.
The read-only Search Console MCP tool supports Search Appearance and remains aggregate-only.
Takeout includes imported facts but never credentials or unsafe provider data.
Desktop/mobile, light/dark, long-locale, keyboard, focus, screen-reader, and reduced-motion behavior are verified.
All supported dashboard locales are updated.
Change-aware QA passes during implementation and the PR-parity profile passes before review.
Alternatives Considered
Polish the current cards only: lower effort, but it leaves reporting fragmented and does not solve data accuracy, pagination, comparison, or recovery limitations.
Build a complete Google Search hub now: URL Inspection, sitemaps, and every Google search type would make this issue too broad and introduce substantially different API, quota, storage, and UX concerns.
Import all search types immediately: image, video, news, Discover, hourly, and preliminary data are better handled as later extensions after the finalized Web Search model is reliable.
Constraints
Keep the integration read-only.
Preserve self-hosted and HitKeep Cloud parity.
Continue using the current read-only OAuth scope and finalized Web Search data.
Keep HitKeep as one deployable application with DuckDB and no new required services.
Preserve site-scoped permissions across REST, dashboard, export, and MCP surfaces.
Do not store or expose raw prompts, credentials, tokens, provider headers, or unrestricted provider error bodies.
Follow Google Search Analytics aggregation and anonymized-query caveats:
Search Console now includes a dedicated performance workspace with comparisons, deeper query and page reporting, Search Appearance insights, clearer sync recovery, and page-level HitKeep outcome context.
Docs Impact
Needed:
Search Console integration/setup guide
Analytics reporting guide
REST API reference
MCP and public analytics skill documentation
Updated screenshots
Release notes
The rendered documentation source is maintained separately; contributors without access should describe the required website updates in the implementation PR.
Additional Context
This should remain one scoped feature issue. Implementation may be delivered in reviewable vertical slices, but the data-model cutover, reporting semantics, recovery behavior, and public contract should be designed together so the workspace does not ship with internally inconsistent totals or states.
Summary
Turn HitKeep's existing Google Search Console settings page and dashboard drilldown into one polished, site-scoped Search Performance workspace for SEO, content, and growth work.
The workspace should combine accurate imported Google Search metrics, previous-period comparisons, Search Appearance reporting, and page-level HitKeep outcomes, while making connection setup, property mapping, sync health, and recovery much clearer.
Problem
The current Search Console surface is useful but fragmented:
Who Benefits
Proposed Solution
1. Create a dedicated Search Performance workspace
Add a site-scoped
/search-consoleroute under Analytics for every authenticated site viewer.Use two query-parameter tabs:
?tab=performance— default reporting workspace?tab=connection— OAuth, property mapping, sync health, retry, and destructive actionsRemove the duplicate Integration navigation item. Redirect the old
/integration/google-search-consoleroute to/search-console?tab=connection, and return OAuth callbacks there.The Performance tab should include:
Search Appearance should be a date-range/comparison table only. It should not be combined with the other dimension filters because the Search Analytics API's aggregation behavior can otherwise produce misleading totals.
2. Add page-level HitKeep outcome context
For each Search Console page row, show same-period HitKeep context derived from the normalized landing-page path:
Clearly label this as outcomes for all HitKeep-tracked traffic landing on that page. Do not present it as Google-attributed traffic or imply causality.
3. Deepen and harden the imported data model
Version
search_console_factswith a dataset discriminator andsearch_appearancesupport.Import finalized Web Search data into seven datasets:
Use:
During a 90-day v2 backfill:
After a property is mapped, request the initial sync automatically. While the page is visible, poll sync status every five seconds and stop when the state is stable or after two minutes.
Include Search Console facts in site/user takeout as
search_console_fact. Never export OAuth tokens, credentials, provider headers, or raw provider error bodies.4. Make connection and recovery states clear
The Connection tab should show a compact status summary and one contextual primary action. Avoid healthy-but-disabled setup controls. Separate destructive actions visually and explain their scope.
Load status, overview, chart, and active table independently so one failed section does not blank the rest of the workspace.
Support localized, actionable states for:
Use skeletons for first load and retain visible data during refresh. Keep last-good reporting available during failed or attention-required syncs, with the relevant recovery action.
Hide mutation controls from read-only users instead of showing disabled controls.
A valid OAuth callback should redirect with a safe success/error code. Invalid or mismatched state should remain an HTTP error and must not expose provider response bodies.
Disconnect copy must explain that every team site mapped through that connection will stop syncing while previously imported data remains. Removing a mapping affects only the current site.
5. Extend the public reporting surface additively
Keep existing routes and response fields backward compatible while adding:
compare_from/compare_toquery_containspage_containsoffsetsortdirectiondimension=search_appearancetotal,limit,offset, andhas_moreon dimension responseshitkeep_contexton page rowsExtend the read-only aggregate MCP tool
hitkeep_get_search_consolewith Search Appearance reporting. Update MCP audit expectations and public analytics procedures.Update both the runtime OpenAPI source and the docs OpenAPI copy.
User Workflow
Success Criteria
Alternatives Considered
Constraints
Explicitly out of scope for this issue:
Release Notes
Search Console now includes a dedicated performance workspace with comparisons, deeper query and page reporting, Search Appearance insights, clearer sync recovery, and page-level HitKeep outcome context.
Docs Impact
Needed:
The rendered documentation source is maintained separately; contributors without access should describe the required website updates in the implementation PR.
Additional Context
This should remain one scoped feature issue. Implementation may be delivered in reviewable vertical slices, but the data-model cutover, reporting semantics, recovery behavior, and public contract should be designed together so the workspace does not ship with internally inconsistent totals or states.