SEOquake implementation handoff
Open work first, then the approved design reference, completed fixes and earlier builds.
4.3.2 released · 4.3.3 follow-ups
4.3.2 is live. Chrome-6 closes the CTA, Links tooltip and SEObar exclusion cards. AI source panel width is reopened for the hotel layout.
29 completed · 1 open
Open work 1
One layout correction remains for 4.3.3. Completed implementations and their references are below.
AI source panel width
Keep Analyze sources aligned with the AI answer column Reopened · 4.3.3
Medium priority · Layout gap in chrome-6 · User screenshots confirmed



November 6 captures. Click any image to view full size.
Issue: On “NYX Hotel London Holborn”, Analyze sources stretches across the wider layout instead of matching the narrower AI answer text. “seo checker” aligns correctly, so the earlier width fix does not cover every Google layout.
Fix:
- In
src/utils/serp/google/ai/detect.ts, tighten the column selection returned bydetectAiOverview. The packaged selector climbs ancestors until source-card containment stops it; it can select a wider wrapper. Use the visible answer column as the sizing reference and validate the hotel layout’s actual DOM before choosing the correction. - In
src/utils/serp/google/ai/controller.ts, size and align the panel host to that column’s outer edges. Keep the scopedResizeObserver, update only changed dimensions and reconnect after Google replaces the column. Do not hard-code 652px or size from the hotel block or right-hand source cards. - Keep
src/components/serp/AiSources.tsxwithin the host width. Preserve list height/scrolling, open state, metric wrapping, source links and CSV export. When the column is unavailable, use a viewport-bounded fallback rather than treating a broad wrapper as a verified answer column.
The selector is unchanged from chrome-4. Controlled 652px/500px layouts still pass; the hotel page’s exact selected DOM element has not been inspected live.
Engineering checks
- Reproduce the hotel query and compare panel edges with the answer text column. Keep “seo checker” and the existing two-column fixture as passing controls; cover layouts with and without visible right-hand source cards.
- Resize/zoom, expand the answer, toggle Google navigation and change queries. Preserve alignment and open state without duplicate panels, horizontal overflow or repeated layout jumps.
- Check long URLs, connected metric rows, Analyze and CSV export. Keep light/dark appearance and the separate source-card metric strips unchanged.
Earlier specification and limited-width verification
The earlier closure is superseded by the hotel-layout evidence above. Preserve the passing checks as regression coverage.
Verified November 6 · chrome-4: The panel matches the answer column’s left edge and width at 652px and 500px, retaining its open state after resizing.
Approved design, specification and engineering checks
Low priority · Layout consistency · Implementation not yet verified
Issue: The expanded Analyze sources panel extends beyond Google’s AI Overview text column. In this capture, our list is 758px wide while the answer column is 652px, leaving their right edges misaligned.
Fix:
- In
src/components/serp/AiSources.tsx, replace the independentmax-w-190sizing on#sq-ai-source-panelwith sizing tied to the visible answer text column. Align the panel’s outer left and right edges with that column; do not include Google’s right-hand source cards or hard-code652px. - Use the panel host in
src/utils/serp/google/ai/controller.tsand the structure identified bydetectAiOverviewinai/detect.tsto establish the correct layout reference. The currentnext.root.before(panel.host)placement does not guarantee a shared column width. Prefer layout inheritance where possible; otherwise measure the text column and apply its width and alignment to the host. Validate the reference across layouts rather than relying on one generated Google class. - If measurement is needed, use a scoped
ResizeObserver, update only when dimensions change, and reconnect when Google replaces the answer container. Clean it up through the controller’s removal/disposal path; avoid polling, scroll-time full-page scans or remounting the panel just to resize it. If the column is temporarily unavailable, retain a viewport-bounded fallback until a valid reference returns. - Keep the existing list height, vertical scrolling, open/closed state, source links, metrics, Analyze and CSV export. Let header controls and metric rows wrap within the narrower panel without clipping or horizontal overflow. Leave
AiSourceCardstrips in Google’s source cards unchanged.
Code references were checked in the local source checkout; confirm their current equivalents in the implementation branch. Captured dimensions are evidence, not fixed layout targets. This changes the expanded source panel only; Analyze sources stays attached to the AI Overview.
Engineering checks
- Compare the panel’s outer edges with the answer text column on layouts with and without right-hand source cards. Test signed-in and Incognito results, light and dark appearance, and AI Overviews before or between organic results.
- Resize and zoom, expand/collapse Google’s answer, and open/close its left navigation. Keep the width aligned without overlap, horizontal scrolling, repeated layout jumps or duplicate hosts.
- Change queries and let Google replace the answer. Reattach sizing to the new column, preserve the panel’s existing lifecycle behavior and remove stale observers.
- Check long titles, URLs and full connected metric rows. Header controls, Analyze links and CSV export remain usable; source-card strips, scrolling and collapse controls remain unchanged.
Completed designs 6
Implemented. See each item’s verification and remaining checks. Still the source of truth for any change to these surfaces.
Final Design
Implemented · 4.2.0Explore the iPhone lineup. Compare models, discover their features, and find the right iPhone for you.
Sep 15: Result position moved into the strip as #3, before Rank; 12px semibold.
Previous build → Final Design
Implemented · 4.2.0Approved design reference. Current package and validation evidence are summarized above.
Light-mode changes below only. Preserve data, loading/error behavior, existing settings, links and tracking except the additions specified here.
| Area | Current · 4.1.2 | Update |
|---|---|---|
| Typography | 13px controls. | 12px Inter (Arial / sans-serif fallback); labels 400 / values 600; 20px line height; tabular, lining numerals. |
| Strip | 2px 7px padding; square corners; 4px / 6px outer margins. | 4px 7px padding; 3px radius; no outer margin, border or shadow. Fill the result column; height follows content. 652px is the preview width, not a production fixed width. |
| Result number | Inside the metric strip, at 14px. | Keep inside the SEOquake strip, first before Rank, as #3. Use 12px / 20px Inter, weight 600, muted #60636B; non-interactive, no tooltip or tab stop. Accessible label: Search result position 3. Do not insert a number beside Google’s title. Preserve numbering and visibility settings; this changes placement, not calculation. |
| Control spacing | 8px padding; 6px internal gap. | 1px 0 padding; 4px internal gap; 24px minimum height; 3px radius. Metric text baseline-aligned; icons centered. |
| Flow spacing | Controls wrap independently. | 9px horizontal / 0px vertical gap. PIN, whois and source wrap independently. Never split a label/value. Reference heights: 32px for one row, 56px for two; allow more rows. |
| Labels and order | Short labels without colons. | #position → Rank: → Traffic: → Costs: → L: → LD: → LRD: → PIN: → whois → source. PIN stays non-clickable. Analyze uses spare space on the last row. |
| Icon sizing | Existing provider and utility icons. | Six Semrush icons + Pinterest: 16 × 16px. Whois/Source: 12 × 12px. Keep icon identities; no additional standalone logo. |
| Colors | Existing gray strip and controls; #11AA88 interaction accent. | Values #181E15; labels and Semrush/Pinterest icons #60636B; utilities #5C6269. Interactive green #00785F. Keep strip #F0F1F2. |
| Hover / focus | Metric label and icon highlight. | Highlight the linked value only; label/icon stay gray. Value focus: 2px green outline, 2px offset, 1px radius. Whois/Source highlight together; focus outline 2px #7137AD, offset 2px. No filled hover background. |
| Transitions | 150ms control transitions in the supplied package reference. | 120ms color/background-color transitions; disable for reduced motion. No entry animation or moving metrics. |
| New behavior | No Analyze link; definitions hidden in the SERP specimen. | Add Analyze, tooltips and the Show tooltips preference, as specified below. |
Analyze CTA
Sep 15: Analyze text and icon changed to #5C5DC4. Example includes #3 and five selected Semrush metrics so the CTA remains visible; default settings are unchanged.
- Fit: after fonts load, measure the last row’s remaining width from its rightmost item to the flow’s right edge, accounting for the result number, selected controls and existing gaps. Recheck on resize, item-size, content or selection changes; no fixed viewport breakpoint.
- Placement: 7px from the right edge, centered on the last existing row—not the panel. Never disable, hide, reorder or displace selected metrics, reserve space, add a row or increase height to fit Analyze; otherwise hide it.
- Style: text/icon #5C5DC4; 12px / 20px Inter, weight 600; padding 2px 4px; minimum height 24px; 12px external-link icon with 6px gap. Underline on hover, no fill; focus outline 2px #7137AD, offset 2px.
- Keyboard: hidden means invisible, non-interactive, excluded from tab order and assistive technology. Restore these when shown. If it disappears while focused, return focus to the nearest preceding visible focusable control, or the strip.
- Link: Domain Overview for the analyzed domain, using the existing helper; new tab with
noopener noreferrer.
Tracking
Use the existing tracking helper with:
utm_source=seoquake
utm_medium=toolbar
utm_campaign=serp_domain_overview
utm_content=serp_cta_analyze
ref=174537735
Tooltips
- One at a time on hover or keyboard focus. Keep open while the trigger or tooltip is hovered, or the trigger is focused; dismiss 150ms after leaving, or immediately on Escape. PIN stays hover-only, not a link or tab stop.
- Fixed position, 6px below the trigger; flip above when needed. Keep an 8px viewport inset; never affect wrapping or Analyze visibility. Use
role="tooltip"and a uniquearia-describedby; remove native titles.
12px / 16px Inter; title weight 600, 2px bottom gap. White background, #181E15 text, 1px #DADDDE border; 8px 10px padding; 4px radius; max-width 280px, capped to viewport minus 16px. Shadow: 0 2px 6px #00000014.
Exact tooltip copy
Reuse the existing Quick View / Full Report definitions:
| Label | Title | Definition |
|---|---|---|
| Rank: | Semrush Rank | A Semrush visibility ranking for the analyzed domain. |
| Traffic: | SE Traffic | Estimated US organic traffic for this domain from Semrush data. |
| Costs: | Traffic Cost | Estimated paid-search equivalent value of this domain's organic traffic. |
| L: | URL Backlinks | Links from other websites pointing to this URL. |
| LD: | Subdomain Backlinks | Total backlinks pointing to tracked subdomains for the analyzed domain. |
| LRD: | Root Domain Backlinks | Total backlinks pointing to the root domain. |
| PIN: | Pinterest Pin Count | Estimated Pinterest pin count for the linked URL. |
| whois | Whois | Ownership lookup helper for the linked domain. |
| source | Page Source | View the page source for the linked URL. |
SERP Overlay preferences
Add Appearance → Show tooltips, enabled by default. Save independently of the SEObar setting; control both standard and connected SERP tooltips, on hover and focus.
Implemented in 4.2.3: Appearance → Theme adds Match Google (default), Light and Dark. See the dark SERP Overlay ticket for the settings and theme rules.
Default selection · Implemented in 4.2.0: Enable SE Traffic by default for SERP Overlay. Keep Traffic Cost and other defaults unchanged; preserve users’ explicitly saved selections. Included in the tested core overlay update.
Implementation: SE Traffic shares the existing Rank API request; enabling it should not require an additional request.
#00785F meets normal-text contrast on these light surfaces. Analyze #5C5DC4 has 4.86:1 contrast on #F0F1F2. This is not a full accessibility sign-off.
Highlight the value
Implemented · 4.2.0Retained implementation reference for SEObar styling and metric defaults.
- On hover/focus, highlight only the linked metric’s value; keep its label and provider icon gray. Whois/Source still highlight icon and label together. Preserve visible focus indicators, non-link counts and loading behavior.
- Use #00785F on light backgrounds, including white menus in dark mode. Keep #18F0BF on dark backgrounds. Apply to green interactive text, control icons and green value-focus outlines.
- Scope component changes to SEObar; use the SERP specs for SERP. Leave Quick View, Full Report, brand fills and status colors unchanged; do not replace the global green palette.
Otherwise preserve layout, typography, spacing, hit areas, icons, tooltips, settings, links and seobar_* tracking. No Analyze CTA or dark-mode redesign for SEObar.
Connected SERP overlay
Implemented · TestedIncluded in 4.2.0 chrome-4. Semrush connection and connected metrics passed user testing on September 17.
Legacy comparison, Final Design and design specifications.
Legacy version
Introducing the iPhone Duo. Plus new iPhone 18 Pro, Apple Watch Series 12, Apple Watch Ultra 4, and AirPods 5.
Final Design
Introducing the iPhone Duo. Plus new iPhone 18 Pro, Apple Watch Series 12, Apple Watch Ultra 4, and AirPods 5.
Connected SERP overlay — design specs
Add the connected Semrush row above the Final Design. These specs cover the new row and connected tooltip differences; the standard SERP specs apply to the lower strip and result number.
| Area | Specification |
|---|---|
| Layout | Above the standard strip in the same full-width panel; no gap, outer border or shadow between rows. Width follows the result column; 652px is the preview reference. Keep the result number first in the lower metric strip, before Rank, following the standard specs. |
| Order and wrapping | AS: → Visits: → Pages/Visit: → Avg. Visit: → Bounce rate:. Wrap whole metrics, keeping icon, label, value and score bar together. Never truncate or hide values. Lower-strip order follows the standard specs. |
| Typography | 12px Inter (Arial / sans-serif fallback); 20px line height; labels 400, values 600; tabular, lining numerals. Match the lower strip. |
| Spacing | 4px 7px row padding; 12px between metrics; 3px internal gap. Controls: no padding, 20px minimum height. Reference heights: 28px top row; 84px total with the two-line lower strip. Height follows content; do not hardcode. |
| Surfaces and colors | Top row #E9EBED; lower strip #F0F1F2. Top corners 3px; preserve 3px bottom corners. Labels/provider icon #60636B; values #181E15. |
| Authority Score | 16 × 16px Semrush icon before AS:. After the value: 32 × 4px score bar, 2px radius, 2px extra left margin; replace orange with #5C5DC4. Preserve score-to-fill behavior; 100 shows a full bar. No icons on the other four metrics. |
| Hover and focus | Interactive values and value-focus outlines #00785F; Whois/Source highlight icon and label together. Labels, provider icons and purple score bar stay unchanged; no filled hover background. Connected controls: 2px #7137AD focus outline, 2px offset. Same light-surface accent as standard SERP/SEObar; leave global brand/status colors unchanged. |
| Tooltip behavior | One across both rows; show after 180ms hover or immediately on focus. Top-row tooltips: 8px above the whole panel when space permits; lower strip: 8px below. Flip outside the panel to fit; keep 8px viewport inset. No layout impact. Dismiss on Escape; the preview also dismisses on pointer exit, blur, scroll or resize. |
| Tooltip appearance | White background; 1px #D8DADD border; 4px radius; 8px 10px padding; max-width 260px. Text #181E15, 12px / 16px Inter; bold title with 2px bottom gap. Shadow: 0 2px 6px #00000014. Preserve approved copy; wrap naturally without forced breaks or clipping. |
Exact connected tooltip copy
| Label | Title | Definition |
|---|---|---|
| AS: | Authority Score | Semrush’s domain reputation score. |
| Visits: | Monthly Visits | Estimated monthly visits from Semrush Traffic Analytics. |
| Pages/Visit: | Pages per Visit | Average number of pages viewed during each visit. |
| Avg. Visit: | Avg. Visit Duration | Average time visitors spend on the site per visit. |
| Bounce rate: | Bounce Rate | Percentage of visits that end after one page view. |
Traffic definitions reuse Full Report copy; Authority Score uses the approved short Semrush adaptation. Example values are screenshot samples, not live data.
Implementation: reuse existing Semrush connection behavior, data sources, formatting, links, tracking and settings. Flag missing capability before implementation.
Completed 65
Implemented. See each item’s verification and remaining checks. The original diagnosis and fix are kept as history.
Quick View trial link
Clarify the unsupported-page CTA and keep the trial line in Quick View Completed implementation · 4.3.3
Verified November 6 · chrome-6: Both connection states use the approved copy and exact destination/tracking values. The secondary trial line stays out of Full Report. Implementation closed; real free-account trial eligibility remains a separate live check.
Approved copy, references and engineering checks
Historical implementation request. The verification above is the current status.
Medium priority · Approved copy and mockups · Revises the chrome-4 trial implementation
Completed: The Quick View trial destination and popup_free_trial / empty_cta tracking work in the reviewed package. The changes below update the wording and correct the Full Report scope leak.


Issue: “Try it on semrush.com” suggests a demo, but opens the homepage or dashboard without explaining what to do next. The trial line also calls connected users “new” and appears in Full Report’s unsupported-page screen.
Approved copy:
- Button, both states: Open semrush.com
- Disconnected: New to Semrush? Start a 7-day free trial
- Connected: Using a free account? Start a 7-day free trial
Fix:
- In
src/components/shared/PageAnalysisState.tsx, useuseSurfaceContextfromsrc/context/SurfaceContext.tsxto scope the new button label and secondary copy tovariant === 'unsupported' && surface === 'popup'. Remove the secondary trial line from Full Report; retain its existing message and primaryAction. - Use the existing
useSemrushConnection().connectedstate for the two trial-line introductions. Connection does not establish a paid plan or website login. Keep the heading, explanation, primary button position and existing line styling. - Change only the Quick View primary label to
Open semrush.com. Keep its existinghttps://www.semrush.comdestination andother / empty / emptytracking inputs:popup_other / empty_empty. - Keep the trial link’s shared
Linkandfree_trial / cta / emptytracking inputs insrc/utils/semrush/utm.ts. Both states use the same tagged destination below. Preserve the connection card’s free-account signup link and the separate Full Report Semrush trial banner.
Tagged trial destination: https://www.semrush.com/semrush-free-trial/?utm_source=seoquake&utm_medium=toolbar&utm_campaign=popup_free_trial&utm_content=empty_cta&ref=174537735
Scope: Copy and placement only. Keep SEObar excluded from Semrush, including its homepage. No new exposure tracking or automatic rollout/revert threshold.
Engineering checks
- Open Quick View on a new tab, browser settings and the Web Store in both connection states. Confirm the exact approved copy, readable wrapping and keyboard activation at the normal popup size.
- Verify both primary buttons retain their destination and
popup_other / empty_emptytags. Both trial links must produce the full tagged URL above, without connection-state suffixes. - With an eligible free Semrush account, follow the trial link and confirm the intended offer is available. Record any eligibility restrictions; this live trial journey remains unverified. Do not treat connection status as subscription detection.
- Open Full Report for an unsupported source tab. Keep its message and primary button, with no secondary trial line or unintended
report_free_trial / empty_ctalink. Preserve paused, reload and migration-error states.
Earlier specification · superseded copy and scope
Historical reference only. The approved copy and Fix above supersede the original button label and connection-state wording.

Medium priority · Approved copy and mockup · Implementation not yet verified
Issue: Quick View’s unsupported-page screen offers a general Semrush button but no direct trial link. Add a secondary route without changing the existing button or its attribution.
Approved copy: New to Semrush? Start a 7-day free trial
Fix:
- In
src/components/shared/PageAnalysisState.tsx, add the line belowActiononly for Quick View’sunsupportedvariant. Use the existing surface context to keep it out of Full Report and other states. Reuse the typography, link treatment and spacing of Quick View’s “New to Semrush? Create a free account” line; keep the approved mockup’s placement and the primary button’s position. - Use the shared
Linkcomponent for “Start a 7-day free trial”, withhref="https://www.semrush.com/semrush-free-trial/"anddestination: 'free_trial',placement: 'cta',panel: 'empty'. With the popup tracking surface,withSemrushTrackingParamsgeneratespopup_free_trial/empty_cta. Do not add a qualifier or connection-state suffix. - Add
'free_trial'toSemrushDestinationinsrc/utils/semrush/utm.tsif still absent in the current branch. Reuse the existing builder and its source, medium and referral values; confirm the resulting URL against the tagged link below. - Leave “Try it on semrush.com” unchanged: label, position, destination and
destination: 'other', placement: 'empty', panel: 'empty'. Its existingpopup_othercampaign andempty_emptycontent stay separate from the new trial link. Keep the free-account signup link on the Semrush connection card unchanged.
Tagged destination: https://www.semrush.com/semrush-free-trial/?utm_source=seoquake&utm_medium=toolbar&utm_campaign=popup_free_trial&utm_content=empty_cta&ref=174537735
Scope: One secondary link in Quick View’s unsupported-page state, such as a new tab, browser settings or the Web Store. Retain that state’s existing connected/disconnected availability; no new account-status targeting, automatic navigation, permission or telemetry request. This is an outbound trial landing-page link, not OAuth or account signup.
Code references were checked in the local checkout; confirm the equivalents in the implementation branch. The separate campaign preserves attribution separation, not a guarantee of unchanged registration volume.
Engineering checks
- Open Quick View on a new tab, browser settings and the Chrome Web Store. Confirm the exact copy and fully visible line below the unchanged primary button at the normal popup size. Check connected and disconnected states.
- Click the new link and verify a new tab opens the exact trial URL with
utm_source=seoquake,utm_medium=toolbar,utm_campaign=popup_free_trial,utm_content=empty_ctaandref=174537735. Preserve keyboard focus and activation. - Click the original button and compare its destination/tags with the previous package:
popup_other/empty_emptyremains unchanged. Confirm the new campaign can be distinguished in the reporting readout; a click does not establish a trial or registration. - Confirm no new trial line appears in paused, reload or migration-error states, ordinary report content or Full Report. Preserve the existing free-account connection-card copy/link.
Links row tooltip
Shorten the Semrush row tooltip Completed implementation · 4.3.3
Verified November 6 · chrome-6: Tooltip content and accessible label use “Analyze in Semrush”. Both Quick View and Full Report Links render the updated action.
Approved copy, references and engineering checks
Historical implementation request. The verification above is the current status.
Low priority · Pending in 4.3.3-chrome-4 · Approved copy

Issue: “Analyze this page in Semrush” repeats context already provided by the link row. Shorten it to match the other action tooltips.
Approved copy: Analyze in Semrush
Fix:
- In the shared Semrush Links row action, change the tooltip’s
contentand the anchor’saria-labelfromAnalyze this page in SemrushtoAnalyze in Semrush. Apply to Quick View → Links and Full Report → Links. - Keep
aria-describedby,anchorRefandcompactModebehavior intact. Preserve the icon, row-specific destination, tracking, hover/focus and Escape dismissal.
Both old strings remain in 4.3.3-chrome-4/chunks/semrush-B_AqKuds.js. Update the source component that generates this action; do not patch the compiled bundle. The local proposal and 4.3.3 Design tab already use the new wording.
Engineering checks
- Hover and keyboard-focus Semrush row icons in both Links surfaces. Confirm the tooltip reads “Analyze in Semrush” without an added heading and the accessible action label matches.
- Click an internal and external row action. Confirm each retains its existing exact-page destination and tracking. Keep the adjacent Find on page control accessible.
SEObar built-in exclusions
Stop built-in exclusions matching unrelated websites Completed implementation · 4.3.3
Verified November 6 · chrome-6: 46 packaged-function checks pass for hostname boundaries, unrelated-site examples, intended exclusions, path/query restrictions and user settings. Semrush remains excluded. These are function checks, not real-site browser tests.
Approved copy, references and engineering checks
Historical implementation request. The verification above is the current status.
Medium priority · Matching flaw confirmed in chrome-4 · Targeted correction
Issue: Built-in URL patterns can hide SEObar on unrelated sites: the Bing rule matches climbing.com and benjaminfranklinplumbing.com, while the Semrush rule matches example.com/?next=semrush.com/. These are unintended exclusions, even when the user has enabled the bar.
Fix:
- In
src/utils/seobar/urlFilters.ts, review all 16DEFAULT_EXCLUDESrules and their use throughDEFAULT_EXCLUDE_EXPRESSIONSinisSeobarAllowedOnUrl. Match the intended hostname and supported subdomains with explicit boundaries; domain mentions in a path, query or user info must not qualify. - Prefer parsed
URL.hostnamefor host checks, with explicit path/query predicates where the original rule requires them. Preserve intended host coverage and restrictions such as search paths; do not turn path-specific exclusions into blanket domain blocks. - Keep Semrush excluded, including the homepage, app and checkout. Preserve user-entered
settings.matchesandsettings.excludesregex behavior, HTTPS settings and existing enable/pause controls. This ticket changes built-in rules, not saved user rules.
Confirmed by evaluating the packaged rule patterns, not by a new live-browser test. This is separate from the completed “For this domain” rule fix. If the full correction cannot be verified in time for 4.3.3, carry it into the next patch rather than ship a partial rule rewrite.
Engineering checks
- With SEObar enabled and no user exclusions, verify
climbing.com,benjaminfranklinplumbing.comandexample.com/?next=semrush.com/are allowed. Userotorooter.comas an unaffected control. - For every built-in rule, cover intended hosts/subdomains and deceptive suffixes such as
bing.com.example.com. Check domain mentions in paths, queries and user info, plus hostname case, ports and trailing-dot normalization. - Confirm real Bing, Semrush and other intentionally excluded destinations retain the intended behavior. Check the existing path/query restrictions explicitly.
- Verify manual regex include/exclude rules, disabled/paused behavior and HTTPS preferences. No changes to the separate user-created domain-exclusion feature.
4.3.3 chrome-4 closeouts
Four chrome-4 closeouts remain complete. The AI panel-width card is reopened above for an additional layout.
Evidence: outputs/package-qa-4.3.3-chrome-4-2026-11-06/report.md. No new memory benchmark; the earlier SERP disappear/reappear observation remains unresolved.
Technical fixes
Semrush panel trial banner
Replace the connected MCP banner with a free-trial CTA Completed implementation · 4.3.3
Verified November 6 · chrome-4: Approved connected-report copy and report_free_trial / semrush_connected_cta tracking pass. The disconnected branch and Quick View MCP tip are preserved.
Approved design, specification and engineering checks
Medium priority · Approved copy and destination · Implementation not yet verified
Issue: Full Report’s connected Semrush panel currently promotes MCP. Replace that banner’s copy and link with the approved free-trial offer, while retaining MCP in Quick View’s connected tips.
Approved copy:
- Headline: See What’s Behind These Numbers
- Body: Get AI visibility, keyword, backlink, and competitor data for any site, all in Semrush One.
- Button: Try Free for 7 Days
Fix:
- In
src/components/report/panels/SemrushPanel.tsx, update only the connected branch’s MCPCtatitle, text and link. Reusesrc/components/shared/Cta.tsxunchanged so the banner keeps its existing position, styling and responsive behavior. Leave the disconnected branch unchanged. - Set the button destination to
https://www.semrush.com/semrush-free-trial/. Passdestination: 'free_trial',placement: 'cta',panel: 'semrush'andconnectionState: 'connected'through the sharedLinktracking. With the report surface,withSemrushTrackingParamsmust producereport_free_trial/semrush_connected_cta; do not use the popup campaign. - Reuse the
'free_trial'addition toSemrushDestinationinsrc/utils/semrush/utm.tsfrom the Quick View trial-link ticket. Add it once if absent; preserve the builder’s source, medium and referral values. - Keep the connected
semrushtip insrc/utils/popup-tips/messages.tsunchanged: “Explore Semrush MCP”, its MCP destination, eligibility, rotation and tracking. Do not remove'mcp'from the tracking types or change other banner/tip placements.
Tagged destination: https://www.semrush.com/semrush-free-trial/?utm_source=seoquake&utm_medium=toolbar&utm_campaign=report_free_trial&utm_content=semrush_connected_cta&ref=174537735
Scope: Full Report → Semrush, connected users only. Copy and outbound link replacement; no new banner, OAuth flow, account-plan targeting or permissions. Preserve the existing new-tab behavior. Trial eligibility remains determined by Semrush’s landing page.
Code references were checked in the local checkout; confirm their equivalents in the implementation branch. The Semrush One wording above is approved for this banner; it does not change the separate free-account connection copy.
Engineering checks
- With SEOquake connected, open Full Report → Semrush. Confirm the exact approved headline, body and button replace the MCP banner in the same location, with readable wrapping and keyboard access.
- Click the button. Verify a new tab opens the trial page with
utm_source=seoquake,utm_medium=toolbar,utm_campaign=report_free_trial,utm_content=semrush_connected_ctaandref=174537735. The original report stays open. - Disconnect and reopen the Semrush panel. Its existing disconnected content is unchanged. Reconnect and confirm the new trial banner returns.
- In connected Quick View → Semrush, verify “Explore Semrush MCP” remains available in the existing tip rotation with its original link and tracking. Confirm the separate unsupported-page trial link still uses
popup_free_trial/empty_cta.
SERP metric tooltips
Use one short description in metric tooltips Completed implementation · 4.3.3
Verified November 6 · chrome-4: All 14 approved descriptions match. The rendered Rank tooltip has no heading and dismisses with Escape; accessible metric names and retry behavior are retained.
Approved design, specification and engineering checks
Low priority · Approved copy · Implementation not yet verified
Issue: SERP metric tooltips repeat the metric name in a bold heading above the description. The extra line makes them larger and covers more of the search results.
Fix:
- Update
SERP_PARAMETER_TOOLTIPSinsrc/utils/parameters/meta.tswith the approved descriptions below. Insrc/components/shared/parameters/ParameterByKey.tsx, stop passingserpTooltip.titleas the visibletooltipTitlefor the SERP variant. Retain the metric’s full name for accessible identification. - In
src/components/serp/overlay/SerpConnectedMetrics.tsx, update the five connected-metric descriptions and omit the visibletitlefromInfoTooltipBubble. Keep one description with the existing body typography and content-sized height; do not leave an empty heading or its spacing. - Apply the same copy through the shared organic-result and expanded Analyze sources metric components. Keep existing tooltip availability in
AiSources.tsx; do not enable tooltips on compact source cards where they are currently disabled. - Preserve light/dark appearance, placement, hover delay, keyboard focus, Escape dismissal and accessible descriptions. Keep the existing “Couldn’t load. Click to retry.” error override and retry action unchanged. Scope this to SERP metric tooltips; do not remove headings globally from the shared tooltip component or alter Quick View, Full Report, SEObar or sidebar-control tooltips.
Approved copy: The first column identifies the current heading; remove it from the visible tooltip. Show only the new description. Current strings were matched in 4.3.3-chrome-3.
| Metric / current heading | Current description | New tooltip |
|---|---|---|
| Semrush Rank | A Semrush visibility ranking for the analyzed domain. | Semrush’s visibility ranking for this domain. |
| SE Traffic | Estimated US organic traffic for this domain from Semrush data. | Estimated US organic traffic for this domain. |
| Traffic Cost | Estimated paid-search equivalent value of this domain's organic traffic. | Estimated cost of buying this domain’s organic traffic through search ads. |
| URL Backlinks | Links from other websites pointing to this URL. | Links from other websites pointing to this URL. |
| Subdomain Backlinks | Total backlinks pointing to tracked subdomains for the analyzed domain. | Backlinks to this domain’s tracked subdomains. |
| Root Domain Backlinks | Total backlinks pointing to the root domain. | Total backlinks to this root domain. |
| Pinterest Pin Count | Estimated Pinterest pin count for the linked URL. | Estimated Pinterest pins for this URL. |
| Whois | Ownership lookup helper for the linked domain. | Look up this domain’s registration details. |
| Page Source | View the page source for the linked URL. | View this page’s source code. |
| Authority Score | Semrush’s domain reputation score. | Semrush’s domain reputation score. |
| Monthly Visits | Estimated monthly visits from Semrush Traffic Analytics. | Estimated monthly visits to this site. |
| Pages per Visit | Average number of pages viewed during each visit. | Average pages viewed per visit. |
| Avg. Visit Duration | Average time visitors spend on the site per visit. | Average time spent on this site per visit. |
| Bounce Rate | Percentage of visits that end after one page view. | Percentage of visits with only one page view. |
Code references were checked in the local checkout; confirm the current implementation-branch equivalents. Keep metric definitions, values, destinations and tracking unchanged.
Engineering checks
- Hover and keyboard-focus standard and connected metrics on organic results and in expanded Analyze sources. Show the exact new description without a bold heading or blank heading space.
- Enable optional parameters, including Pinterest, Whois and Page Source. Verify their copy and actions. Keep disconnected locks and failed-request retry behavior intact.
- Check Light, Dark and Match Google appearance. Text remains readable, the tooltip fits the viewport and does not obscure or intercept neighboring controls. Escape and moving focus away dismiss it correctly.
- Confirm the Show tooltips setting still works, compact AI source cards retain their existing tooltip availability, and other SEOquake surfaces are unchanged.
Quick View Audit banner
Add a dismissible site-audit trial banner Completed implementation · 4.3.3
Verified November 6 · chrome-4: Approved copy and tracking, both connection states, Show tips gating and independent persisted seven-day dismissal pass. Reopening preserves dismissal; expiry restores eligibility without changing tip dismissals.
Approved design, specification and engineering checks
Medium priority · Approved copy and mockup · Connected and disconnected users

Issue: Quick View’s Audit tab ends after the page checks, often leaving unused space. Add a clear next step for users who want to audit the whole site.
Approved copy:
- Headline: You Checked One Page. Now Audit the Whole Site.
- Body: Scan your site for 140+ SEO and AI search issues, and see what to fix first.
- Button: Try Free for 7 Days
Fix:
- In
src/components/popup/panels/AuditPanel.tsx, place the banner after the passed section, outside itsCollapsible, in the existing scroll flow. When there are no passed checks, keep it below the remaining audit content. Do not pin it above the tip bar or limit eligibility to pages with few issues; expanding passed checks moves the banner below that content. - Reuse the purple treatment from
src/components/shared/Cta.tsx, adapting the content/button stack to the popup mockup without changing existing Full Report banners. Reuseclose.svgand the close-control treatment fromshared/layout/TipBar.tsxin the top-right corner, with an accessible label such as “Dismiss site audit offer” and room for the headline to wrap. - Gate visibility on
settings.general.showTipsfromuseAppSettingsand a separate persisted banner dismissal. Wait for settings and dismissal storage to load before showing it, so a dismissed banner does not flash. Apply the same rule to connected and disconnected users; do not infer paid-plan or trial eligibility from connection status. - Follow the
#importsstorage pattern insrc/utils/popup-tips/storage.ts, but use a dedicated banner key, for examplelocal:popup.auditTrialDismissedAt. On X, hide immediately and persist the dismissal time for7 * 24 * 60 * 60 * 1000milliseconds. The dismissal applies across pages and popup reopenings in that browser profile. After expiry, show it on the next eligible Audit view; no background polling is needed. Clean up any storage subscriptions and handle write failures without treating an unsaved dismissal as persisted. - Keep the banner key independent of
local:popup.tipDismissals,dismissPopupTipand tip rotation. Closing the banner must not dismiss the tip bar; closing the tip bar must not dismiss this banner. Turning Show tips off hides both, but does not erase or restart the banner’s seven-day clock. - Use the shared
Linkwithhref="https://www.semrush.com/lp/website-audit-1/"anddestination: 'site_audit',placement: 'cta',panel: 'audit'. The popup surface producespopup_site_audit/audit_ctathroughwithSemrushTrackingParamsinsrc/utils/semrush/utm.ts. Omit connection-state suffixes and qualifiers;site_auditalready exists in the destination type. - Remove only the Audit tip with
ctaText: 'Open Site Audit'fromsrc/utils/popup-tips/messages.ts. Keep the other Audit tips, including the internal “View audit report” action, and leave Full Report Site Audit CTAs unchanged. Verify rotation still handles the reduced list. The old tip usedaudit_tip, while this banner usesaudit_cta; removing it prevents future campaign-level mixing, but historicalpopup_site_audittotals still include prior tip traffic.
Tagged destination: https://www.semrush.com/lp/website-audit-1/?utm_source=seoquake&utm_medium=toolbar&utm_campaign=popup_site_audit&utm_content=audit_cta&ref=174537735
Scope: One banner in Quick View → Audit only, not other tabs, Full Report or unsupported-page states. Reuse existing storage permissions and outbound new-tab behavior. Clicking the CTA does not start the dismissal clock; X does. Trial eligibility remains with Semrush’s landing page.
Code references were checked in the local checkout; confirm current implementation-branch equivalents. Copy and destination are user-approved; the offer’s live eligibility and “140+” claim were not independently verified in this handoff edit.
Engineering checks
- Check connected/disconnected Audit views with zero, few and many issues, including no passed checks. Confirm the exact copy, compact purple styling and top-right X. Expand passed checks and scroll: the banner follows the content and never covers the list or tip bar.
- Dismiss the banner, switch pages/tabs, reopen Quick View and restart the browser. It stays hidden in that profile. With a controlled clock or saved test timestamp, verify it remains hidden just before seven days and returns on the next eligible Audit view at or after expiry. Do not wait a real week or poll in the background.
- Dismiss the tip bar and banner independently. Toggle Show tips off/on while each is dismissed and after expiry; neither dismissal resets or hides the other. Exercise initial storage loading and a failed save without a dismissed-banner flash or unhandled error.
- Activate CTA and X with keyboard. Verify focus remains usable after dismissal. CTA opens a new tab with the exact approved tags, with
audit_ctafor both connection states, and leaves the current report intact. - Confirm “Open Site Audit” no longer enters Audit’s tip rotation, the remaining tips still rotate, and the Quick View MCP tip, other trial CTAs and Full Report banners are unchanged. Compare attribution using campaign plus content and release date, not campaign totals alone.
4.3.2 and 4.3.3 verified fixes
Implementation closeouts. Submission, publication and final release smoke checks are separate.
Google redirect metric recovery Completed implementation
Verified November 5: 4.3.2-chrome-3 resolves the tested delayed HTTP 200 continuation and respects bounded waits, validation and credential omission. Beatus’s Incognito smoke review passed recovery, pagination and correct Analyze destinations. Submitted November 5 at 10:30 a.m. EST; Beatus subsequently confirmed approval, the Store-installed smoke pass and 100% rollout at 2:20 p.m. EST that day. The correction is also merged and fixture-tested in 4.3.3-chrome-3. The separate disappear/reappear observation remains unresolved. Evidence: outputs/package-qa-4.3.2-chrome-3-2026-11-05/report.md and Beatus’s live review.
Unresolved observation · metrics disappear and reappear
Unresolved observation: Beatus saw metric strips disappear together and reappear seconds later in 4.3.2-chrome-3. The cause is not established. Preserve this for targeted reproduction; the redirect fix and later smoke pass do not prove it resolved. Progressive loading alone is a separate behavior.
Original requirements, visuals and engineering checks
Historical November 4 review below. The closeout above supersedes its former open status; original evidence and mockups are preserved.
Medium–high priority · Partially implemented · Live review November 4 · 4.3.2-chrome-2
Completed: Position numbers render independently of destination lookup. All eight organic results were numbered in live review. Bounded retries are running; controlled checks also passed delayed recovery, changed links and navigation.
Issue: Five of eight organic results still had no metric strip. Refreshing changed which results displayed metrics but did not clear the issue. The background capture recorded five Google /goto URLs returning HTTP 200 on all three attempts. The inspected response was HTML without a Location header; the resolver accepts only validated redirect destinations and discards the response body.
Investigation and fix direction:
Engineering discretion: Use these points as a starting point. Investigate other causes or approaches if the evidence supports them. The required outcome is reliable metric strips for the correct result URLs, while preserving working position numbers, security safeguards and performance.
- In
redirectsBackground.ts, capture and inspect a failing HTTP 200 response before it is discarded. Establish whether it provides a valid exact destination or whether the result contains another reliable source for that URL. - Recover and validate the exact destination before loading its metric strip. The implementation approach remains unverified; do not assume every HTML response contains a usable URL or prescribe a parser before inspecting it.
- Preserve the independent numbering and bounded retry/backoff behavior in
resolveOpaqueGoogleRedirect. More retries alone will not resolve the repeated HTTP 200 case. - Keep the result-identity and
href-change handling indetectResults/syncOverlays. Retain known-good metrics only for the same result; never attach another page’s metrics. - Retain credential omission, manual redirect handling and batched observation. Do not visit every result automatically or guess exact destinations from abbreviated display URLs.
Still to establish: The HTML body was unavailable in DevTools because the resolver cancels or aborts it. We have confirmed the response mismatch, but not whether the body contains a destination, an interstitial or another response. Verify the chosen correction on real Incognito results before closing this ticket.
Files: src/utils/serp/google/redirectsClient.ts, redirectsBackground.ts, google/base/detect.ts, google/base/observe.ts, google/base/positionNumber.ts and src/utils/serp/syncOverlays.ts. Confirm the current source equivalents; change source, not generated bundles.
Live evidence · November 4 · 4.3.2-chrome-2
All eight positions appeared. Metric strips were present for Backlinko, Yoast and Chrome Web Store, and missing for Seobility, SEOptimer, Semrush, Rank Math and DebugBear. After one refresh, a changed result set still had five missing strips. The network capture included 15 HTTP 200 responses across five lookup URLs, with three attempts per URL.

The initial page was inspected before opening worker DevTools. The refreshed load was captured with DevTools open, which keeps the worker awake. No product code or settings were changed.
Original diagnosis and user screenshots · November 3
In 4.3.0 and 4.3.1, a failed destination lookup was cached without expiry or automatic retry, hiding both the number and metrics. Controlled tests confirmed that flaw. The 4.3.2 candidate corrects numbering and retry behavior; the remaining live response case is described above.
The first capture shows positions 5, 8 and 9; the later capture shows 1, 4, 7 and 8. Numbers and entire metric strips change together. These are full-page references; sponsored results are expected to remain unnumbered.


Engineering checks
- Test direct links and real Incognito
/gotolinks with ads and AI modules between organic results. Every eligible organic result keeps its correct number. - Cover delayed success, temporary failure followed by success and permanent failure. Verify bounded requests, recovery without a full reload and no fabricated destination or metrics.
- Add the captured HTTP 200 HTML case, including the same response on all three attempts. Verify the destination is recovered from validated evidence when available; an unsupported or invalid response must not produce guessed metrics.
- Repeat real Incognito searches and refreshes, including
seo checker. Confirm consistent strips across eligible results with resolvable destinations and investigate any remaining omissions before acceptance. A controlled redirect fixture alone does not close this ticket. - Change a result link in place, trigger repeated rescans and test Back navigation. Numbers remain stable; overlays recover on the correct result and never show stale metrics from another page.
- Confirm normal-profile rendering, SERP export ordering and existing performance behavior remain intact.
Acceptance: Keep the passed position-number behavior. Resolve the observed live missing-strip case using verified exact destinations, with consistent rendering after refresh and no stale or fabricated metrics. Unsupported responses remain safely unresolved. Do not close the ticket while the reproduced live omissions remain unexplained.
Evidence: Current live findings: outputs/serp-overlay-live-followup-2026-11-04/evidence.json. Earlier controlled package checks: outputs/package-qa-4.3.2-2026-11-03/report.md. Original investigation: outputs/serp-position-investigation-2026-11-03/report.md, static-findings.md and redirect-cache-results.json. These are workspace evidence references, not public downloads.
Quick View Links: six implementation revisions Completed implementation
Verified November 5: All six corrections pass focused checks in 4.3.3-chrome-3: action tooltips, matching Full Report routing, Clear filters, disabled zero-count options, anchor variants and highlight context. Background checks, filtered CSV and highlight lifecycle checks also pass. This is package verification, not a new user live smoke test or Store release. Final live smoke review remains part of release readiness; the sidebar placement ticket is still open. Evidence: outputs/package-qa-4.3.3-chrome-3-2026-11-05/report.md.
Original requirements, visuals and engineering checks
Historical November 4 review below. The closeout above supersedes its former open status; original evidence and mockups are preserved.
Medium priority · Reviewed package: 4.3.3-chrome · Package checks and Beatus’s live review, November 4
Completed: The Links tab, occurrence-level filtering, background checks after popup closure, highlight persistence and filtered CSV download passed focused package checks. Preserve these behaviors and the existing Semrush destinations, tracking and permissions.
Design reference: 4.3.3 Links redesign and Technical specs. Track the remaining revisions here; keep the approved mockups intact.
1. Keep action tooltips clear of neighboring buttons


Issue: Download and highlight tooltips can cover neighboring action buttons and intercept clicks. Users must dismiss the tooltip before they can use the covered control.
Fix:
- Adjust the Links action buttons’
InfoTooltipBubbleplacement anddata-tooltip-boundaryhandling so tooltips stay clear of adjacent controls. Changingpointer-eventsalone is not enough: neighboring buttons must remain visible and clickable. - Review
interactiveand pointer-event handling for these informational tooltips. Cover Find broken links, Show these links on the page / Clear highlights, and Download this list as CSV / Downloaded; preserve focus and Escape dismissal.
2. Open the matching Full Report Links section
Issue: View Full Report opens Page Info while Quick View’s Links tab is active, losing the user’s report context.
Fix:
- Update
getReportTargetFromPopupTabinsrc/utils/surface/navigation.tsto map the Links tab to the Links report. - Pass the selected Internal/External
kindthroughHeader/NavButtontoopenReportFromPopup. Keep the source tab and existing report-dropdown routes intact.
3. Add Clear filters to the empty state

Issue: An unmatched search leaves users with an empty list and no single action to reset the search and filters.
Fix:
- In the Links empty-state renderer, use No links match these filters. and add Clear filters, matching the mockup.
- Reset
queryto empty andfollow/statustoall. PreservekindandstatusByUrlso the selected section and completed checks remain intact.
4. Gray out zero-count filter options

Issue: Zero-count filter options look available and can be selected, leading to an empty list.
Fix:
- Use each option’s existing count to apply
disabledand the approved muted styling in the Follow and Status menus. Keepallavailable as a reset option. - Update the menu’s Arrow/Home/End focus handling to skip disabled options. Recalculate availability when the scope, search or other filters change.
5. Show additional anchor variants
Issue: Grouped URLs show one anchor and an occurrence count, but give no indication that other occurrences use different anchor text.
Fix:
- Derive distinct variants from each filtered row’s
occurrences, usinganchorTypeplus whitespace-normalizedanchorText. Render +N more for the variants beyond the displayed anchor. - Use the collector’s existing image-alt text; do not invent labels for SVGs or empty anchors. Repeated empty anchors of the same type count as one variant; empty text, IMG and SVG variants remain distinct because their displayed badges differ.
- Keep
buildLinkRowsURL grouping andoccurrenceCountunchanged. Repeated identical anchors must not increase the variant count; preserve occurrence-level filtering and Mixed handling.
6. Include the selection in the highlight chip

Issue: The highlight chip shows only a count, so users cannot see which scope and follow filter remain active after Quick View closes.
Fix:
- Build the content-script chip text from the active
links:page:highlightfilters:kindandfollow. For example: 19 external dofollow links highlighted; omit the follow qualifier forall. - Keep the existing highlighted-occurrence count, Clear action, popup-close persistence and navigation cleanup.
References checked against the 4.3.3 package and existing shared source. Apply changes in the corresponding source components, not generated bundles.
Engineering checks
- In the native Quick View popup, download CSV and move directly to Clear highlights or Find broken links. Both remain visible and work on the first click while the download tooltip is open. Repeat with the highlight tooltip and move between all three controls in both directions. Check hover, focus and Escape.
- From Quick View → Links → Internal and External, click View Full Report. Each opens the matching Links section. Check the explicit report dropdown and other Quick View entry points for regressions.
- Combine search, follow and status filters to produce no matches. Clear filters restores the selected scope’s list without discarding check results. Confirm visible focus and keyboard activation.
- Verify zero-count options are muted and unavailable, and become available when the applicable counts change. Keep reset options usable.
- Use one URL with two different anchors and repeated identical anchors. Verify +N more counts distinct additional variants while the occurrence count remains correct. Cover Mixed, Dofollow and Nofollow filtering, repeated empty anchors, different image-alt text and SVG anchors. Same-type empty repeats count once; different anchor types remain distinct.
- Highlight Internal/External and All links/Dofollow/Nofollow selections. Close Quick View and verify the chip’s wording and count, Clear action and navigation cleanup.
- Additional check, not a confirmed live bug: Test longer status badges such as Couldn’t check (HTTP 403) and Rate limited (HTTP 429). The short Couldn’t check badges passed Beatus’s visual review. The package uses truncation classes; confirm longer labels remain fully readable without clipping or overlap, as specified in the design.
- Retain background-check completion after popup closure, filtered CSV naming and exclusions, existing Semrush links/tracking and the current permission set.
The separate missing Google metric-strip issue remains on the existing 4.3.2 SERP recovery card. It is not duplicated here.
4.3.2 · Reviews and feedback
Add permanent review and feedback links Implemented · 4.3.2
Closed November 4 · 4.3.2 package checks and Beatus’s live confirmation
Completed: Write a Review appears beside Send Feedback in Full Report. Earlier package verification confirmed that the exact Store reviews URL opens in a new tab and preserves the report. Beatus confirmed the implemented footer in 4.3.2 on November 4 and supplied a live Page Info screenshot. Closed by product review; this does not record a Store release.
Original scope and engineering checks are retained below for reference. The timed review banner remains out of scope.
Original issue: Full Report already offers Send Feedback, but has no permanent Write a Review link alongside it. Give users a simple way to share their experience without interrupting their work.
Fix:
- Add Write a Review beside Send Feedback in Full Report’s shared footer navigation. Preserve the other footer links. Apply consistently across report sections.
- Point Write a Review to https://chromewebstore.google.com/detail/seoquake-on-page-seo-chec/akdgnmcogleenhbclghghlkkdndkjdjc/reviews. Open it in a new tab, preserving the current report. This opens the reviews page; the user selects Write a review there.
- Keep both links available to connected and disconnected users from first use. Match the existing footer typography, spacing and keyboard focus. Do not add a report tab or a prominent primary button.
- Use neutral labels. Do not ask for five stars, offer incentives or route users according to whether their feedback is positive or negative.
Scope: The below-report banner in the mockup is a later proposal. Do not implement it, usage thresholds, dismissal timers or review-completion detection in this ticket. No new telemetry or permissions are requested.
Files: src/components/shared/layout/Footer.tsx and the existing shared Link component. Reuse the current external-link behavior.
Design reference · footer links only
The supplied mockup is preserved in full. Only the footer’s Write a Review link beside Send Feedback is in scope. The banner above the footer and the two illustrated backlink CTA states are not changes requested by this ticket.

Engineering checks
- Check every Full Report section in connected and disconnected states. Exactly one Write a Review link appears beside the existing Send Feedback link.
- Click Write a Review from the installed extension. Confirm the correct production Store listing’s reviews page opens in a new tab and the report remains intact. Check signed-in and signed-out Store sessions without submitting a test review.
- Confirm Send Feedback still opens its existing form. Test keyboard navigation, visible focus and narrow-width wrapping without clipping.
- Confirm there is no banner, automatic prompt, rating gate or new permission request.
Completed in 4.3.1
19 implementation cards closed from package checks and live review, including the final light-tooltip correction. Beatus confirmed the Store upgrade smoke test and 100% rollout setting on November 2. Historical requirements and engineering checks are preserved inside each card; the new redirect-recovery issue is tracked separately above.
Use light tooltips in Quick View and Full Report Completed · 4.3.1
Closed November 3, 2026 · Final package and live review passed
Completed: Quick View and Full Report retain light tooltips under either system appearance. SEObar and SERP Overlay retain their own theme behavior. The final SEObar 3 package passed 12 browser scenario groups, followed by Beatus’s live smoke test. Original issue and implementation guidance follow as history.
Original requirements, visuals and engineering checks
Issue: Quick View and Full Report stay light, but their shared tooltip styles respond to the system’s dark preference. Tooltips can therefore use a dark background on the white report. SEObar and SERP Overlay already follow their own selected appearance.
Fix:
- Resolve the shared
Tooltipappearance from its owning surface. Keep Quick View and Full Report tooltips light under both system preferences, including tooltips rendered through a portal. - Reuse the existing light treatment: white background, dark heading/body text, light border and current shadow. Apply the same appearance to the arrow. Keep the approved copy, sizing, spacing and placement.
- Preserve SEObar’s selected Light/Dark appearance and SERP Overlay’s Light/Dark/Match Google behavior. Avoid changing the global
dark:selector or removing dark support from shared tooltips. - Keep hover, keyboard focus, Escape dismissal, accessible associations, interactive links and the current delegated tooltip lifecycle unchanged. This is a theme correction, not another tooltip implementation.
Scope: Quick View and Full Report tooltip appearance only. No report dark-mode feature, new preference or changes to metric-error styling.
Files: Shared tooltip renderer and the app’s surface/theme wiring. src/components/shared/Tooltip.tsx is the local source reference; confirm its current source equivalent. In the reviewed package, chunks/download-Bb8NZV5h.js contains renderer Ro and assets/download-D9G6iL8w.css applies tooltip dark: styles through prefers-color-scheme. Change source, not generated bundles.
Earlier appearance · October 28 references


Engineering checks
- With light and dark system preferences, inspect metric and information tooltips in Quick View and Full Report. Background, text, border and arrow must retain the existing light appearance.
- Check SEObar in Light and Dark, and SERP Overlay in Light, Dark and Match Google. Explicit choices must work even when they differ from the system preference.
- Verify hover, keyboard focus, Escape, placement and stacking. Interactive tooltip links must remain usable; no clipped popup tooltips, duplicated tooltips or lingering invisible overlays.
Acceptance: Tooltips follow the owning surface’s appearance. Quick View and Full Report stay light; the existing SEObar and SERP appearance controls retain their behavior.
SEObar memory across open tabs Completed · 4.3.1
Closed October 28, 2026 · Targeted memory optimization verified
Completed: Chrome 3 SEObar includes a smaller content UI, shared stylesheets with fallback/cleanup, delegated tooltip listeners and shared connection subscriptions. The targeted optimization produces a repeatable, modest memory reduction.
Previous measurement · October 27
Measured result: Across 30 controlled article tabs, Chrome 3 SEObar used 1,845.5 MiB of aggregate browser-process footprint versus 1,887.5 MiB for Chrome 3: a 42 MiB reduction. Paired savings were 38 and 46 MiB. Tab JavaScript heap fell from 73.03 to 65.91 MiB, about 9.75%, and median listeners fell from 245 to 190 per tab. The 10-tab comparison also improved.
October 28 comparison: At 30 tabs, Chrome 3 used 1,890.5 MiB of aggregate browser-process footprint, Chrome 3 SEObar 1,845 MiB and SEObar 2 1,849 MiB. Tab JavaScript heap was 72.75, 65.84 and 65.60 MiB respectively. SEObar 2 retains a 2.2% footprint and 9.8% heap reduction versus Chrome 3 before the optimization. All 12 captures passed validation.
Interpretation: There is no meaningful additional memory gain over the first optimized package. The paired footprint change reverses direction: 4 MiB lower, then 12 MiB higher. Both optimized builds retain a median 190 listeners per tab versus 245 in Chrome 3. These are controlled memory results, not a demonstrated page-speed improvement.
Completed interaction check: Package tests passed tooltip hover, keyboard focus and Escape after layout changes. Beatus’s October 28 live review also passed tooltip dismissal and the exposed Top/Bottom positions. The separate S-key typing fix is complete.
Closeout: The targeted optimization and interaction checks are complete. No further testing or memory work is requested for this card.
Future consideration: Revisit broader memory optimization only if slowdown complaints persist or engineering identifies a specific improvement worth measuring. Scope that work separately; this card does not require ongoing testing.
Measurement limits: The October 28 benchmark reran all three builds with two repetitions in reversed order, fresh Chrome for Testing profiles, 10 and 30 local article tabs, eight-second settling windows and post-GC heap readings on a Mac. Aggregate process footprint is not extension-only memory or exact unique physical RAM. These results do not establish Windows performance, connected-account memory use, a long-session leak or a dramatic page-speed gain.
Files: src/components/seobar/SeobarApp.tsx; src/components/seobar/layout/; src/components/seobar/parameters/; src/assets/styles/seobar.css; src/entrypoints/seobar.content.ts and shared content-UI style, tooltip and subscription helpers.
Engineering checks · regression reference
- Retain the now-passed tooltip interaction checks as regression coverage: hover, keyboard focus, placement and Escape after layout changes.
- Preserve the verified performance change, metrics, preferences, connection state, layouts and existing-tab controls alongside the completed hotkey correction.
- For any later memory change, repeat matched enabled/off comparisons and inspect retained-object ownership. Do not use feature removal as evidence of an optimization.
Status: Completed. These checks are a reference for future changes, not outstanding work on this card.
Shared regression checks · preserve repeat-visit caching
Working as tested: All three sequences made four API requests on the first visit and zero on the immediate repeat. The three cached metric entries survived natural worker termination with their original fetch timestamps. The post-restart request count was not captured. This is a regression check, not another defect or a replacement for the audit-header cache fix.
- Keep cold and repeat visits separate. With the same selected parameters and fresh session cache, verify that repeat visits reuse valid entries instead of restarting every metric request.
- Allow the worker to stop naturally without DevTools keeping it alive. Revisit the page and confirm that valid entries survive without stale URL/account data. Check expiry and account-change behavior, including connected metrics.
- Retest saved preferences, Semrush connection and metric/CSV completeness after each performance change. Compare the final candidate with the unchanged baseline.
S shortcut blocks typing in embedded text fields Completed · 4.3.1
Verified October 28: 48 focused package checks passed for native, nested, open and closed shadow editors, shortcut guards and horizontal/vertical layouts. Beatus’s October 28 live review confirmed intact typing, S toggling outside text fields and logo expansion. The composition guard was tested synthetically; no physical OS IME test is claimed.
Original requirements and engineering checks
Historical specification. The verified closeout above supersedes its open status.
High priority · Confirmed in 4.3.0, Chrome 3 and Chrome 3 SEObar
Issue: With SEObar’s “Minimize to icon” setting enabled, typing S inside some embedded editors toggles the bar instead of entering the letter. useSeobarMinimize checks only event.target. For fields inside shadow DOM, that target is the outer component rather than the editable field, so the handler calls preventDefault() while the user is typing.
Fix:
- Update
isEditableTargetand thehandleKeyDownguard to considerevent.composedPath()and the active editing context, including editable ancestors and supported textbox/editor controls. Skip the shortcut whenever focus is in a text-entry control. - Handle closed shadow components conservatively. Their internal fields are not exposed in the event path, so
composedPath()alone is insufficient. When the editing state cannot be established, allow the key through rather than suppressing the typed character. - Ignore composition and already-handled events, and review repeated keydown events and physical
KeySmatching so other keyboard layouts do not lose text. Preserve existing modifier exclusions and click-to-expand behavior.
Scope: The existing SEObar shortcut handler in horizontal and vertical layouts. Protect typing without requiring users to discover a setting or workaround. Do not redesign SEObar or add a new shortcut preference as part of this fix.
Files: src/hooks/useSeobarMinimize.ts, including isEditableTarget, handleKeyDown and its document capture listener. Source path is a reference; matching logic was independently verified in both supplied Chrome 3 packages.
Engineering checks · typing and shortcut behavior
- With “Minimize to icon” enabled, type
asand uppercase S in ordinary inputs, textareas and contenteditable editors, plus each equivalent inside open and closed shadow DOM. Text must arrive intact and typing must not toggle the bar. - Check focused nested editor content, supported rich-editor/textbox controls, composition input, key repeats and non-Latin layouts. These are required regression cases, not claims that every one was already reproduced.
- Confirm the intended shortcut still works in clearly nonediting page contexts. Preserve Ctrl/Meta/Alt combinations, click-to-expand, horizontal/vertical layouts, pause/resume and existing-tab settings changes.
- Verify the packaged build. The prior controlled test passed all nine no-extension controls and all ordinary fields, while all 18 shadow-field checks across three packages lost S.
Acceptance: SEOquake never consumes text entry to activate the S shortcut. Ambiguous editor contexts must favor typing.
Evidence · package reproduction and uninstall feedback
October 27 controlled browser tests used actual unchanged packages and trusted key events: 36 valid editable-control checks across a no-extension baseline, 4.3.0 chrome-5, 4.3.1 chrome-3 and chrome-3-seobar. All six open/closed shadow input, textarea and contenteditable controls lost S in each package. Ordinary input, textarea and contenteditable controls worked.
The latest uninstall survey contains two explicit S-key complaints (October 12 on 4.2.2 and October 23 on 4.3.0), plus one nonspecific typing complaint (October 19 on 4.3.0). This is not four confirmed hotkey reports. The users’ websites are unknown, so the reproduction establishes a matching mechanism rather than proving every report’s cause.
Domain exclusions also hide SEObar on unrelated sites Completed · 4.3.1
Verified October 28: Newly generated rules escape the selected host and enforce its boundary. All 23 browser checks and 87 packaged-function checks passed. Beatus’s October 28 live review confirmed Backlinko stayed excluded across reload and another page while Wikipedia remained enabled.
Existing rules: Older saved expressions are preserved because generated and manual rules share the same list without provenance. An old broad rule can still overmatch; adding a new rule does not override it. Remove or edit the affected old rule before recreating the exclusion. This closes the new-rule correction, not an automatic migration.
Original requirements and engineering checks
Historical specification. The verified closeout above supersedes its open status.
Medium priority · Confirmed in Chrome 3 SEObar · Inherited from legacy 3.13.5
Issue: “For this domain” builds an exclusion by appending window.location.host to ^http(s)?://. The hostname’s dots are treated as regex wildcards, and the pattern has no host boundary. Excluding example.org therefore also hides SEObar on unrelated hosts such as examplexorg and example.org.other.test.
Working behavior: The exclusion saves and remains effective on the selected host through navigation, reload, a new tab and browser restart. This is a matching correction, not a fix for lost settings. Legacy 3.13.5 generated and evaluated the same pattern.
Fix:
- Make
buildDomainExcludePatterntreat the selected host as literal text and enforce the end of the host. Escape regex metacharacters and use a proper boundary, or use an equivalent structured host comparison. Retain HTTP/HTTPS handling and the current explicit-port behavior. - Preserve the current host scope. Excluding
example.orgmust not silently expand towww.example.orgor other subdomains. Site-wide exclusions and changes to the control’s wording are separate product decisions. - Keep manually entered regex rules working through
isSeobarAllowedOnUrl. Review how previously generated exclusions can be corrected safely; do not rewrite stored entries whose origin or intent cannot be established. KeepappendSeobarExcludePatterndeduplication and existing settings persistence intact.
Existing rules: The current list stores generated and manual expressions together without a provenance marker. Robert should identify a safe treatment for old generated entries and state any remaining limitation. A matching-looking string alone is not proof that it was generated automatically.
Scope: SEObar’s “For this domain” action and its generated host-exclusion rules. No change to the Google SERP overlay, global pause, whitelist behavior, custom regex semantics or default visibility.
Files: src/utils/seobar/urlFilters.ts (buildDomainExcludePattern, appendSeobarExcludePattern, isSeobarAllowedOnUrl); src/components/seobar/layout/SeobarCloseDropdown.tsx. Confirm the source equivalents in the current implementation before editing; supplied-package matching logic was independently verified.
Engineering checks · exact host matching and persistence
- Use the actual close menu on
example.org. SEObar disappears there and stays absent on another path, after reload, in a new tab and after browser restart. - Confirm
examplexorg,example.org.other.testand an unrelated control still display the bar after the exclusion. Verify they display it before the test as well. - Confirm
www.example.organd sibling subdomains retain the current independent behavior. Check HTTP/HTTPS and a host with an explicit port without broadening the approved scope. - Keep intentional custom regex exclusions, whitelist entries and duplicate handling unchanged. Test the selected treatment of older generated rules alongside manually entered patterns; document ambiguous entries rather than silently rewriting them.
Acceptance: Newly generated rules exclude only the selected host under the existing scope. Unrelated hosts remain unaffected, custom regex rules keep their meaning, and handling of older entries is explicit.
Evidence · current package and legacy behavior
October 27 checks used the unchanged 4.3.1-chrome-3-seobar package in an isolated Chrome for Testing profile. Actual menu actions confirmed same-host persistence through browser restart and reproduced both unrelated-host false exclusions. Exact packaged-function checks confirmed the same matching behavior.
The legacy 3.13.5 package’s data/plugins.js builds the same pattern in handleExcludeClick and evaluates it with new RegExp(r, 'i') in checkMatch. This is inherited behavior, not a newly introduced rebuild regression. The uninstall respondent’s website is unknown; these findings do not prove the cause of that individual complaint.
Metric error text disappears on light reports Completed · 4.3.1
Verified October 28: The shared report error label stays dark and Retry stays blue under both system preferences. Package tests cover Pinterest, Backlinks and SE Traffic. Beatus’s October 28 live screenshots show a readable Pinterest error followed by successful Retry to a numeric zero. Request recovery remains complete.
Original requirements and engineering checks
Historical specification. The verified closeout above supersedes its open status.
UX-01 · Low priority · Styling correction only
Completed: Pinterest failures now show an error and remain eligible for Retry and Request all parameters. HTTP 429/500 and transport-failure recovery passed in both Chrome 3 packages. Genuine zero stays numeric; a successful empty response stays n/a. Previously completed Backlinks, domain and AI-source retry work remains complete.
Issue: With a dark system color preference, the white Full Report displays “Couldn’t load” in white. The shared error label uses text-gray-darker dark:text-white, so the system preference changes the text without changing the report surface. Retry remains visible and works. This is a presentation issue, not a recurrence of the Pinterest recovery bug.
Fix:
- In the shared metric-error component used by the Links table, remove the OS-triggered
dark:text-whitefrom the light report label anddark:text-lavenderfrom its Retry control. Keeptext-gray-darkerandtext-blueso both remain readable on the white report under either system preference. - Scope the change to the light app/report error treatment. If the source component also serves a genuinely dark surface, use an explicit surface variant. Preserve the separate
serp-ui.jserror renderer and overlay theme styles; do not change the global dark-mode selector. - Keep
role="status", Retry’s accessible name, keyboard focus andonRetryunchanged. Preserve the working Pinterest service/message handling, manual and bulk retry, and zero/empty formatting. No request or retry orchestration changes are needed.
Fix validation: Removing only those two classes in a temporary browser DOM override kept the label dark under both system preferences. Retry remained readable and recovered a real zero. This validates the color correction; the rebuilt source patch still needs the checks below.
Files: Shared metric failure renderer used by the Full Report Links table and metric cards. In 4.3.1-chrome-3-seobar/chunks/semrush-Ck9Hqxg5.js, it is li, exported as Q (formatted lines 3143–3156). Locate the source equivalent by Couldn’t load and its label/onRetry props; the older local checkout does not establish the new source filename. Do not patch generated bundles.
Engineering checks · error contrast and preserved recovery
- Force a Pinterest failure in the white Links report under both light and dark system preferences. “Couldn’t load” must be readable and Retry must remain visible, keyboard-accessible and functional.
- Check failed Backlinks and domain-metric cells that reuse the renderer. Confirm manual Retry and Request all parameters still recover failed cells without re-requesting successful cells.
- Confirm the separate SERP and AI-source error treatment remains readable on light and dark overlay surfaces, including explicit appearance choices that differ from the system preference.
- Keep genuine zero and successful no-data responses distinct from failures. This correction must not change response/cache behavior.
Acceptance: Error text is readable on the surface where it appears, and the verified retry behavior is preserved.
Previous requirements and verified retry work
October 26 requirements retained for traceability. The Chrome 3 completion and styling-only revision above supersede the former Pinterest failure report.
UX-01 · Low priority · Revision required for 4.3.1 chrome-2-perf
Completed: Backlinks and domain-metric errors, manual and bulk recovery, AI-source retry, independent metric-group state and CSV zero/n/a handling passed the focused package checks.
Issue: A failed Pinterest request still becomes {ok:true,count:null}. Links shows n/a without Retry, and Request all parameters skips that cell after recovery. Beatus reproduced this offline and online in the same report. This is a low-priority failure-path edge case.
Fix:
- Preserve HTTP and network failures at the Pinterest service/message boundary instead of turning them into a successful empty response. Reuse the existing Links error state to show “Couldn’t load” with Retry.
- Keep failed Pinterest cells eligible for Request all parameters. Skip successful and in-flight requests; retry only on user action.
- Keep successful empty responses as
n/aand genuine zero counts numeric. Preserve the completed retry behavior for other metric groups.
Scope: Pinterest failure handling and recovery only. This remaining edge case does not alone block 4.3.1.
Files: Pinterest service/message handler in background.js (reviewed functions Mt and Kt); src/components/report/panels/LinksPanel.tsx; src/components/report/panels/links/LinksTable.tsx. Use the source equivalents when implementing.
Original scope and completed work
Historical October 26 requirements. At that review, only Pinterest failure handling remained open; Chrome 3 subsequently completed it. The current revision above concerns error-text contrast only.
Issue: In Full Report → Links, a failed Backlinks, domain-metric or Pinterest request is stored as loaded, with an error that is never shown. The cell displays n/a, the same as a successful response with no data, and Load all skips it. AI Overview source cards follow the same pattern for public metrics: a failed request leaves n/a and the source is marked as requested, so it is not tried again until the page reloads. A temporary timeout or rate limit reads as “this site has no data”.
Fix:
- In
LinksPanel’srequestMetric, keep a failed request distinguishable from a successful empty one for all three metric groups. Today thecatchpaths setloaded: truewith anerrorthat nothing renders. Render the error state in the metric cell as “Couldn’t load” with a Retry control; keep n/a only for successful responses without data. Keep errors separate by metric group, so a Backlinks request cannot clear a Pinterest failure or vice versa. - Load all includes unrequested eligible cells and retries failed cells, while skipping successful and in-flight requests. A cell retries only on a user action (Retry or Load all); add no automatic retry loops.
- For AI Overview sources, allow a user-initiated retry of failed public metric groups. In
ai/metrics.ts,load()returnsentry.loadPromisebefore checkingentry.requested. An explicit retry must clear or replace that settled promise, reset the requested state as needed and replace a faileddomainRequestsentry for the origin. Preserve successful group data, shared in-flight deduplication and the current navigation/disposal guards. Match the existing connected-metric retry (retryConnected) in placement and behavior. - Keep connected-metric loading, retry controls and their copy unchanged.
Scope: Full Report Links metric cells and AI Overview public metrics, where the verification confirmed the pattern. Check SEObar, SERP result rows and Quick View Semrush metrics for the same error-to-n/a conversion; include them only if they share it, and list them in the change. A page or report reload already retries, because failures are not cached.
Files: src/components/report/panels/LinksPanel.tsx; src/components/report/panels/links/LinksTable.tsx; src/utils/serp/google/ai/metrics.ts; src/components/serp/AiSources.tsx.
Engineering checks · Pinterest recovery and regression coverage
- For each Links metric group, simulate a timeout, HTTP 429 and 500 responses and going offline. The cell shows the error with Retry instead of n/a. After the service recovers, Retry fills the value. Load all includes unrequested eligible cells and failed cells, while skipping successful and in-flight requests.
- Run Backlinks and Pinterest requests together with one failing and the other succeeding, then reverse the outcomes. Each cell retains its own result or error; starting or completing one group must not clear the other group’s failure.
- A successful response without data still shows n/a and is not requested again by Load all. Real zero values stay numeric.
- Fail public requests for one AI Overview source and wait for the original
entry.loadPromiseto settle. Retry issues a fresh request and restores failed values without replacing successful group data or duplicating active requests for sources on the same origin. Test a second failure followed by recovery. Connected retry controls behave as before. - Retry is a named button (for example “Retry Backlinks”), reachable by keyboard and visible in light and dark themes. Error text is announced without moving focus.
- CSV exports must not write a number for a failed cell. Keep the current export value for missing data.
Acceptance: Verify on the rebuilt extension with controlled failures. Pinterest recovery was unimplemented at the October 26 review and passed in Chrome 3. Retain these functional checks as regression coverage; only the contrast correction remains open.
Backlinks CTAs should open the current page Completed · 4.3.1
Verified: Both connection states generate the analyzed page’s full URL with Exact URL scope, approved copy and distinct tracking. Beatus’s October 27 live review confirmed https://backlinko.com/best-free-seo-tools remained selected through the Semrush authentication gate and in the opened report. Screenshots show Exact URL before and after authentication. The card is closed; the screenshots do not identify a separate new-account registration test.
Original requirements, visuals and engineering checks
Historical specification below. The closeout above supersedes its former open status.
Low priority · Product revision · Both connection states

Issue: Both Links-tab Backlinks CTAs open a domain report, even when the user is analyzing an individual article. The original domain-preservation fix is complete and worked as specified. This revision makes the destination match the page being analyzed.
Fix:
- Use the analyzed report’s page URL for both connected and disconnected CTAs. Open
/analytics/backlinks/overview/with the encoded full URL inqandsearchType=url. Use Exact URL scope, notdomainorsubfolder. Reuse the existing page-backlink URL handling; retain the meaningful path and query. - Preserve the distinct connected/disconnected tracking through
ctaConnectionTracking('backlink_analytics', connected), includingreport_backlink_analyticsand the state-specificutm_content. Connection state changes the copy and possible sign-in gate, not the target page. - Keep the current headings and buttons: connected “Now See Who Links Back” / “Open Backlink Analytics”; disconnected “Get Your Free Backlink Report” / “Check Backlinks”. Use the supporting copy below in both states.
- Keep the exact page selected after Semrush sign-in or signup. SEOquake connection and the website’s login session are separate states.
Approved supporting copy: See which sites link to this page, how authoritative they are, and where those links point.
Scope: The Backlinks CTA below Full Report → Links in both connection states. No changes to unrelated domain metrics, report-scope controls or other Semrush destinations.
Files: src/components/report/panels/LinksPanel.tsx and the existing Backlinks URL/tracking helpers. The reviewed package already uses searchType=url for page-backlink metric links.
Engineering checks
- Analyze
https://backlinko.com/best-free-seo-tools. Both CTAs open that full URL with Exact URL selected, rather than the root domain or a subfolder. - Check a homepage, nested path, subdomain, encoded characters and a meaningful query string. Use the report’s analyzed URL, not a different active browser tab.
- Verify both states retain their existing tracking and approved copy. Check signed-in access, existing-account sign-in and new-account signup; record which journeys were actually exercised.
- After authentication, confirm the page URL and Exact URL scope remain selected. Do not treat the previous domain sign-in test as verification of this new URL behavior.
Acceptance: Both CTAs reach the same exact-page report with their existing attribution intact.
Remove the Keyword data tooltip Completed · 4.3.1
Verified: Chrome 3 and Chrome 3 SEObar show no Keyword data tooltip or browser title on hover/focus. The accessible description, query/country destination and tracking remain intact. The approved row and Opus’s reference mockups are preserved below.
Original requirements, visuals and engineering checks
Historical specification below. The closeout above supersedes its former open status.
CRO-07 · Low priority · Copy revision for 4.3.1
Completed: The Keyword data row, query/country destination and tracking are implemented. Package checks and live review passed.
Issue: The visible tooltip repeats the query already shown in Google. Remove it; keep the approved row and accessible description.
Fix:
- Remove the visible tooltip from “Keyword data”, including any browser
titletooltip. Keep its descriptive accessible name, current query and new-tab information. - Keep the existing label, icon, placement, destination, locale handling, tracking and keyboard focus unchanged.
Implemented design · reference
Visual: shipped 4.3.0 sidebar compared with the proposed row, for the query “what is seo”.
Captured from the shipped 4.3.0 package on a local Google results page at 2x; live Google was not loaded. The proposed row is built from the Export CSV row’s own markup, so its spacing, color, hover and focus classes match. The icon is the Semrush mark already used on result metrics.
Implemented row requirements
Fix:
- Add one row under Export CSV in the expanded sidebar, using
ParameterControl’s stack layout: the Semrush icon and the label “Keyword data”. It is a link that opens in a new tab. - Link to
https://www.semrush.com/analytics/keywordoverview/?q=<query>&db=<database>. Use the trimmed, URL-encoded Google query. Hide the row when the query is empty. Keep the destination current when Google changes the search query without a full reload. - Choose the database with
resolveSemrushDatabaseCountry, using the appliedsettings.googleGland current Google URL, as result rows and Analyze links do. Germany opensdb=de; preserve the helper’s fallback for unset or unsupported countries. Do not treat the search phrase as a target domain or derive the database from the language. Preserve the existing Set locale navigation. - Track with the shared
Linkhelper: surfaceserp,destination: 'keyword_overview',placement: 'cta',panel: 'serp'and qualifierresearch_keyword. The explicit panel is required because the sidebar has no current panel ID. That generatesutm_campaign=serp_keyword_overviewandutm_content=serp_cta_research_keywordwith the standard source, medium andref, a new campaign that can be measured on its own.
Revision · October 21: Remove the Keyword data tooltip. Repeating the search query adds clutter because it is already visible in Google’s search field. Keep the row label and screen-reader description; no replacement tooltip copy is needed.
Label: the sidebar leaves about 88px for a row label at 13px. “Keyword data” (84px) fits. “Research keyword” (113px) and “Keyword Overview” (115px) would truncate. Keep the implemented label.
Preserved behavior: Hiding the row for queries with operators such as site: or inurl: is a product choice, not an approved requirement. Keep the implemented original-query behavior; do not strip operators as part of the tooltip revision.
Scope: One placement, in the expanded sidebar only. The collapsed tab is unchanged, and the row hides with the other tools when the SEOquake overlay is unchecked. No result-row or AI Overview keyword links in this ticket; measure this campaign before adding more placements.
Files: src/components/serp/SerpControlPanel.tsx; src/components/shared/parameters/ParameterControl.tsx; src/utils/semrush/utm.ts; src/utils/semrush/databaseCountry.ts.
Engineering checks
- Check single words, multi-word phrases, quotes, non-Latin scripts and very long queries. The URL is encoded and the label never truncates.
- Select Germany and apply Set locale. After the existing Google navigation, the link uses
db=de. Check unset and unsupported countries against the helper’s fallback, and confirm that a language-only change does not select a country database. - Change the Google search query without a full reload; the link and accessible name use the new query. Empty queries hide the row. Test operator queries against the confirmed behavior without silently rewriting them.
- Check hover and keyboard focus in light and dark themes against the Parameters and Export CSV rows, including the sidebar’s mint focus ring in dark mode.
- Hover and keyboard focus show no tooltip for Keyword data. The link still works by keyboard, keeps its visible focus ring and exposes the descriptive accessible name.
- Verify the landing page for signed-out, free and paid accounts. Do not imply unlimited keyword data; flag any limit that contradicts the label.
- Verify the final URL includes
utm_campaign=serp_keyword_overview,utm_content=serp_cta_research_keyword, the encoded query, country database and standard source, medium andref. Confirm the campaign appears in attribution reporting before judging the experiment. A click is not a registration.
Acceptance: Verify on the rebuilt extension with the real Keyword Overview journey. This ticket does not claim a measured conversion increase.
Audit results change after the background worker stops Completed · 4.3.1
Verified: Captured HTTP status and noindex survived natural worker shutdown in the reviewed package. Same-tab navigation and uncaptured-page/PDF checks passed.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: After Chrome stops the background worker, SEOquake can lose the page’s HTTP status and response headers. A captured 200 response becomes an error, and a page with X-Robots-Tag: noindex can appear indexable. The recorded chrome-5 test reproduced this after 30 seconds idle. The root cause also exists in 4.2.3.
Fix:
- Register network and tab-cleanup listeners synchronously. Preserve enabled and paused behavior while settings initialize; do not collect while SEOquake is paused.
- Keep the required network observations in session storage and restore them before answering report requests. Associate them with the correct tab and navigation. Clear closed-tab data and invalidate stale observations when the page changes.
- Distinguish a response that was not observed from an observed response with no robots header. Missing capture must not become an HTTP failure, an indexable verdict or a healthy summary count. Apply the same distinction to the combined Noindex result and PDF output.
Copy to confirm: The label and explanation for an unobserved response still need review. The required behavior is settled: do not show a definitive pass or failure without captured evidence.
Files: src/entrypoints/background.ts; src/utils/page/messaging/registerBackgroundNetworkHandlers.ts; src/utils/page/messaging/pageNetworkHandlers.ts; src/utils/page/cache/; network-dependent analyzers in src/utils/page/analyzers/.
Engineering checks
- Load a page returning
200andX-Robots-Tag: noindex. Compare Quick View, Full Report and PDF before and after natural worker termination. Captured noindex remains blocked. Run without DevTools keeping the worker alive. - Navigate while the worker is stopped, and analyze a page already open before extension installation. Uncaptured data stays unknown rather than becoming a definitive pass or failure.
- Navigate to a different URL in the same tab. The new document must not inherit old response headers. A captured
200response without a robots header retains its normal result. - Check pause/resume, settings initialization, tab closure and session restoration. Keep saved preferences and existing report navigation intact.
Acceptance: Run these checks on the rebuilt extension. Verification identifies the existing defect; it does not establish that a fix has shipped.
Standard robots directives produce false warnings Completed · 4.3.1
Verified: Focused parser, report and PDF checks passed for permissive, restrictive and crawler-scoped directives.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: Common Yoast and Rank Math directives such as max-image-preview:large and max-snippet:-1 trigger warnings in Meta Robots and Noindex Tag. The shared parser also misses bot-scoped headers such as googlebot: noindex. These results misrepresent the page’s indexing directives.
Fix:
- Evaluate directive values and bot scopes in both parsing paths. Permissive
max-*values should not trigger restrictive-directive warnings; do not blanket-allow every value. - Preserve meaningful handling of
noindex,none, restrictions and conflicts. A bot-scopednoindexmust not produce an unqualified indexable result. - Keep Meta Robots, X-Robots-Tag and Noindex Tag consistent. Preserve agent scope rather than silently applying one bot’s directive to every crawler.
Files: src/utils/page/analyzers/metaRobots.ts; src/utils/page/helpers.ts; src/utils/page/analyzers/noindex.ts; src/utils/page/analyzers/xRobotsTag.ts.
Engineering checks
- Test
max-snippet:-1,max-video-preview:-1andmax-image-preview:large, separately and together. They must not produce restrictive-directive warnings. - Test restrictive values such as
max-snippet:0,noindex,none, multiple meta/header values and conflicting follow directives. Retain the relevant restriction and scope. - Test
googlebot: noindexalongside unscoped directives. Check all three related results, including the combined Noindex check. Missing network capture follows the unknown-state handling above.
Acceptance: Run these checks on the rebuilt extension. Verification identifies the existing defect; it does not establish that a fix has shipped.
Responsive pages fail when CSS cannot be inspected Completed · 4.3.1
Verified: Cross-origin CSS and fluid-layout fixtures returned neutral results; PDF and summary handling passed.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: The responsive-design check counts readable media rules. Cross-origin stylesheets are skipped, and a zero count produces a failure even when the viewport is valid. Responsive pages using CDN CSS, nested rules or fluid layouts without media queries can therefore fail this check.
Fix:
- Track whether the relevant stylesheets could be inspected and traverse accessible nested rules where supported.
- Do not infer a responsive-design failure from zero readable media rules. Cover unreadable CDN CSS and valid fluid layouts, not just the cross-origin exception.
- Use an inconclusive result when the available evidence cannot establish responsiveness. Keep the separate viewport findings; a valid viewport alone does not prove a responsive layout.
Status and copy to confirm: The inconclusive label and explanation still need review. Do not substitute an automatic pass or keep a false failure while choosing the wording.
Files: src/utils/page/collectors/responsiveDesign.ts; src/utils/page/analyzers/responsiveDesign.ts.
Engineering checks
- Compare fixtures using same-origin media rules, nested media rules, unreadable cross-origin CSS and a valid fluid layout without media queries.
- The CDN and fluid-layout cases must not fail solely because the collector found no media rules. A valid viewport alone must not create a responsive-design pass.
- Check invalid and missing viewport tags separately. Review the agreed inconclusive label in Quick View, Full Report, summary counts and PDF.
Acceptance: Run these checks on the rebuilt extension. Verification identifies the existing defect; it does not establish that a fix has shipped.
Page text can invalidate a valid Analytics setup Completed · 4.3.1
Verified: Valid GA4 plus unrelated body text remained valid. Malformed tracking configuration and body-only text stayed distinct.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: The Analytics collector scans the entire page HTML for tracking-like IDs. Ordinary text such as G-20 summit can be treated as an invalid ID and make a valid Analytics setup fail. A valid GA4 ID plus this body text reproduced the false result.
Fix:
- Collect IDs from supported tracking scripts and configuration contexts. Do not treat arbitrary page copy as tracking configuration.
- Preserve supported GA4, Universal Analytics and Tag Manager detection. A malformed ID in an actual tracking configuration must still be identified; unrelated text must not override a valid setup.
Files: src/utils/page/collectors/analytics.ts; src/utils/page/analyzers/googleAnalytics.ts.
Engineering checks
- A valid GA4 setup plus
G-20 summitin body text remains valid. The same body text without tracking code must not establish an Analytics installation. - Check supported GA4, Universal Analytics and Tag Manager configurations. A malformed ID in an actual tracking configuration remains actionable.
- Confirm the same result appears in Quick View, Full Report and the Audit PDF. Do not change other audit checks or the 28-check total.
Acceptance: Run these checks on the rebuilt extension. Verification identifies the existing defect; it does not establish that a fix has shipped.
SEObar code loads when nothing will display Completed · 4.3.1
Verified: Off, paused and excluded fixtures avoided full UI work. Existing-tab enable/disable and pause/resume checks passed.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: Pages still load and compile the SEObar bundle when SEObar is off, SEOquake is paused or the page is excluded. The off and paused cases used about 6–7 ms of extension script work at normal CPU and 27 ms at 4×. The excluded-page check also used about 27 ms at 4×, with no visible bar.
Fix:
- Keep the initial script small. Check the current settings and page eligibility before loading the SEObar UI, styles and other expensive dependencies.
- Verify the packaged output actually keeps that UI separate. The existing dynamic import is inlined into the shipped bundle, so changing the source import alone is not enough.
- Preserve settings changes, pause/resume and navigation in already-open tabs. If changing content-script registration, account for scripts already injected into those tabs.
Expected benefit: Less repeated processing where the bar will not appear. The measured script time is a target to reduce, not guaranteed page-load savings.
Files: src/entrypoints/seobar.content.ts; src/utils/seobar/visibility.ts; src/utils/seobar/urlFilters.ts; src/utils/seobar/watchPageUrl.ts; packaged content-scripts/seobar.js.
Engineering checks
- Compare the shipped baseline and rebuilt package on enabled, SEObar-off, globally paused and excluded pages. Inspect loaded scripts as well as the visible UI. The full UI bundle must not load where it is not needed.
- Enable and disable SEObar, pause and resume SEOquake, and change exclusions with tabs already open. Check normal navigation, history navigation and pages that update their URL without a reload. Avoid duplicate bars, listeners or timers.
- Repeat the normal-CPU and 4× checks with the same pages, observation window and five runs per condition. Report the actual reduction; keep saved preferences and the existing default behavior.
- Run the shared cache checks. Confirm that the normal enabled path still loads its metrics and report shortcuts.
Acceptance: Verify the built package and record before/after results. No implementation or measured savings are claimed yet.
Resource-heavy pages generate unnecessary background messages Completed · 4.3.1
Verified: The resource-heavy fixture recorded fewer worker message events while tested network evidence remained correct. This is reduced overhead, not elimination.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: Broad network listeners observe requests across tabs and resource types. On the 300-image test page, the worker received 2,505 messages with SEOquake enabled and 2,431 with SEObar off. Worker processing was 26.1 ms and 23.5 ms respectively. These are messages, not separate worker starts.
Fix:
- Map each listener to the report evidence that needs it. Narrow request types, URLs and collection lifetime where that evidence can still be captured correctly. Restrict redirect tracing to the requests that need it.
- Coordinate this with the 4.3.1 network-observation fix. Preserve synchronous listener registration, session restoration, tab/navigation ownership and unknown-state handling.
- Retain original navigation status, response headers, redirects and required image evidence. A later fetch is not a substitute for the original response, especially on authenticated pages. Keep permission removal or optional-permission changes out of this fix.
Expected benefit: Less background work on pages with many requests. The exact reduction needs a candidate build; the independent run did not isolate each listener's cost.
Files: src/utils/network/redirectCapture.ts; src/utils/page/messaging/registerBackgroundNetworkHandlers.ts; src/utils/page/messaging/pageNetworkHandlers.ts; src/utils/page/cache/mainFrameNetworkCache.ts; src/utils/page/cache/imageResponseSizeCache.ts; src/entrypoints/background.ts.
Engineering checks
- Compare the baseline and candidate on the article and 300-image fixtures, with SEOquake enabled, SEObar off and globally paused. Measure worker messages and processing separately from page-load time. Verify a repeatable reduction. Measure report-opening latency too, and confirm that deferred collection preserves responsiveness and complete audit evidence.
- Run all network-observation acceptance cases, including natural worker termination, missing capture and a captured
X-Robots-Tag: noindexresponse. - Test concurrent tabs, redirects, authenticated pages, navigation in the same tab and tab closure. Check image evidence, Quick View, Full Report and PDF results against the baseline.
- Keep link checks on demand and preserve recognized logout/action-link filtering. Run the shared cache checks and verify paused behavior.
Acceptance: Confirm both the reduced work and unchanged audit evidence on the rebuilt extension. Performance gains must not turn missing evidence into a healthy result.
SERP Overlay adds processing on Google pages Completed · 4.3.1
Verified: The perf package reduced processing in controlled comparisons. Beatus’s connected live Google/AI review and both CSV exports passed. Windows and real-world timing gains are not established.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: The verified ten-result fixture added about 582 ms of page processing and 95 ms of blocking time at 4× CPU throttling. All ten overlays rendered in each extension run. The SERP bundle also loads on Google pages where there are no web results. These measurements describe browser processing, not the size of a rebuild or guaranteed page-load savings.
Fix: Investigate before choosing the rendering changes. Separate the small page-eligibility check from expensive results UI. Profile startup, overlay creation, repeated rendering and rescans to find the dominant costs. Propose a targeted change that keeps the existing design and functionality. The fixture confirms overhead; it does not establish the best rendering fix.
Coverage to complete: Test real Google results and AI Overview with Semrush connected and disconnected. Google served a verification challenge during the independent live check. Authentication succeeded, but the connected timing harness failed before recording measurements. Windows and lower-memory hardware remain untested.
Files: src/entrypoints/serp.content.tsx; src/utils/serp/syncOverlays.ts; src/utils/serp/google/match.ts; src/utils/semrush-connected/cache.ts; packaged content-scripts/serp.js.
Engineering checks
- Profile the verified ten-result fixture and real results before changing the render path. Compare five baseline and candidate runs over the same observation window. Record processing, long tasks and time until usable metrics; do not treat shifted post-load work as eliminated work.
- Check Google home, web results and other search modes. A
/search*path alone does not identify web results. Preserve supported navigation into and out of results pages. - Verify all expected overlays, position numbers, inserted/removed results, AI source cards, light/dark appearance, tooltip layering and sidebar controls. Keep country/language and metric selections intact.
- Test connected and disconnected metrics on cold and repeat visits. Confirm authenticated metric responses, not just the connection label. SERP and AI-source CSV exports must include all eligible results, including anything loaded lazily.
- Run the shared cache checks. Repeat on a lower-powered Windows machine when available; keep that limitation explicit until tested.
Acceptance: First return the profile evidence and proposed change. Then demonstrate reduced work and passing functional checks on the rebuilt extension. A redesign or rebuild is not prescribed.
Connect Semrush directly and update the signup copy Completed · 4.3.1
Verified: Package checks and Beatus’s live authorization, automatic refresh and existing free-account metric checks passed. The bottom banner also passed live review; the earlier isolated result is superseded for closeout. The pending card was explained by an open OAuth tab. New-account registration was not separately tested.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: Connect Semrush opens Settings → Integrations before users can start connecting. The connection card asks whether they already have an account, while the signup prompt still promotes Semrush One. Remove the extra settings step and give new users a clear free-account option.
Fix:
- Start the existing OAuth flow directly from connection CTAs in Quick View, Full Report and the first-result SERP teaser. Reuse
startSemrushAuth()through the existing connection flow instead of the Settings navigation callbacks. Keep source-tab context for returning to the report. Keep Settings available for managing or disconnecting the account. - Require an explicit click. Preserve the random, single-use authorization state, its 10-minute expiry, callback validation, existing scopes and token handling. Do not hard-code a standalone authorization URL or expose credentials to the host webpage.
- Keep the original page/report available. Prevent duplicate starts throughout authorization, handle cancellation and failure with a retry option, and refresh connection status and metrics after success. The existing
useSemrushConnectionhook’sbusystate covers launch only; opening OAuth is not a completed connection. - Apply the approved copy below to the shared connection card in Quick View and Full Report. Replace the associated Semrush One signup promotion with the free-account link. Keep the existing layout and responsive behavior. The compact SERP teaser keeps its current copy for this ticket; only its Connect action changes.
- For signup links, add
signuptoSemrushDestinationand usedestination: 'signup', placement: 'cta', panel: 'semrush'with the sharedLinkhelper. Use/signup/; generatepopup_signuporreport_signupby surface, preserving the attribution fields below.

Approved copy:
- Headline: See Authority Score, visits and engagement data
- Body: Connect a free Semrush account to see these metrics.
- Button: Connect Semrush
- Line below: New to Semrush? Create a free account
Signup link and tracking: Use https://www.semrush.com/signup/. Add signup to the shared tracking destinations. Keep utm_source=seoquake, utm_medium=toolbar, utm_content=semrush_cta and ref=174537735. Use utm_campaign=popup_signup in Quick View and report_signup in Full Report. Remove the old semrush_one destination from these signup links so the helper does not overwrite the new campaign. Do not change unrelated promotions or add these signup UTMs to the OAuth URL.
Scope: Signup creates an account; Connect authorizes SEOquake to use it. Verify the new-account journey and available free-account metrics before shipping this copy. Do not imply unlimited data access. The approved first-result lock icons are covered by the separate teaser ticket, and the header status entry point by the status ticket.
Files: src/components/shared/semrush/LockCta.tsx; src/components/popup/panels/SemrushPanel.tsx; src/components/report/panels/SemrushPanel.tsx; src/components/serp/overlay/SerpConnectedMetrics.tsx; src/hooks/useSemrushConnection.ts; src/utils/semrush-auth/messaging/authHandlers.ts; src/utils/semrush-auth/oauthState.ts; src/utils/semrush/utm.ts.
Engineering checks
- From Quick View Overview and Traffic Analytics, Full Report and the first-result SERP teaser, click Connect once. The normal Semrush authorization flow opens without requiring a second click in Settings. Verify any connection banner in the same surfaces uses the same behavior.
- Test signed-in and signed-out accounts, cancellation, failed requests, retry and repeated clicks. The original page/report remains available. A successful connection refreshes the relevant UI and metrics without a manual reload.
- Confirm invalid, expired and replayed authorization state and an unexpected callback origin are rejected. Preserve existing permissions, account-disconnect behavior and secure background token handling. A shortcut to the same flow is not a replacement for its security checks.
- Verify both signup destinations and their final generated tracking parameters. Walk through new-account creation and returning to connect SEOquake. Confirm which Authority Score, visits and engagement data a free account can actually access; flag any mismatch with the approved copy before release.
- Check the longer headline in Quick View and Full Report at their supported widths. Keep wrapping readable, button focus visible and loading/error states clear. Keep actual zero values unchanged. Disconnected placeholder changes are scoped to the teaser ticket.
- Measure connection success and signup completion separately where supported. A CTA click is not a completed connection or registration. Confirm signup attribution with the analytics owner; do not infer conversion gains from click counts alone.
Acceptance: Verify the rebuilt package and the real authorization/signup journeys. No implementation, security certification or conversion lift is claimed by this handoff.
Show locks instead of disconnected teaser zeros Completed · 4.3.1
Verified: Five disconnected locks and the absent teaser gauge passed. Connected Authority Score 0, traffic n/a formatting and live exports remain unchanged.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: When Semrush is disconnected, the first organic result shows placeholder zeros for Authority Score, Visits, Pages/Visit, Avg. Visit and Bounce Rate. These are not measured values. They can make the result look like it has no authority or traffic instead of showing that an account connection is needed.
Visual: shipped 4.3.0 compared with the proposed locks, on result 1 with the top of result 2.



Captured from the shipped 4.3.0 package on a local Google results page at 2x; live Google was not loaded. The proposed frames change only the five disconnected values: each becomes the repository’s lock.svg at 12px in the label colour, and the AS gauge is removed. Screen readers would hear “Authority Score: connect Semrush to view” instead of a zero.
Connected reference: an actual Authority Score of 0 keeps its numeric value and gauge. Zero traffic already displays n/a, because formatTrafficMetrics (src/utils/semrush-connected/trafficAnalytics.ts) treats visits of 0 or less as no data.
Fix:
- Replace those five disconnected placeholder values with small lock icons. Keep the metric labels, order, existing strip styling and connection prompt. Show this teaser only on the first organic result, as it does today.
- In
ConnectedMetric, select locks only forstatus === 'disconnected'. KeepSerpOverlay’s first-result visibility rule. Do not use a zero-value or falsy-value check. LeaveformatTrafficMetricsunchanged and preserve existing connected-value formatting: Authority Score 0 stays numeric with its gauge; zero or unavailable visits retain the traffic formatter’sn/abehavior. - Gate the Authority Score gauge with
!disconnected && score != nullso the teaser does not imply a measured score of zero. Keep the gauge and its normal behavior for actual connected scores, including 0. - Use
lock.svgat 12px in the label colour, matching the mockups. Provide accessible text such as “Authority Score: connect Semrush to view” for each locked metric; do not announce a numeric zero. Preserve existing tooltip keyboard access and verify visibility in light and dark themes. - Keep the icons non-interactive. The existing Connect CTA remains the action, with direct OAuth covered by the connection-flow ticket. No extra sign-in controls or permission changes are needed.
Scope: Only the disconnected connected-metrics teaser on the first organic result. Leave the separate SE Traffic and other standard metrics unchanged. Preserve connected values, missing-data labels, loading indicators and retry behavior. Disconnected AI Overview cards currently omit Authority Score; do not add locks or change their layout as part of this ticket.
Files: src/components/serp/SerpOverlay.tsx; src/components/serp/overlay/SerpConnectedMetrics.tsx; src/assets/icons/lock.svg. Keep the change scoped where shared metric components are reused.
Engineering checks
- While disconnected, confirm that result 1 shows five labeled locks, no placeholder zeros and no Authority Score gauge. Later organic results must not gain this teaser. Keep the Connect prompt visible.
- While connected, test zero and nonzero API values for all five metrics. Authority Score 0 keeps its numeric value and normal gauge. With zero or unavailable visits, traffic and engagement fields retain the formatter’s
n/aoutput. With positive visits, preserve the existing formatting of valid zero engagement values. Missing data must not become zero or a lock. - Check initial connection checking, loading, partial success, request errors and retry. Connect and disconnect without reloading the results page; the row must switch between its normal metric states and the locked teaser.
- Check light and dark Google, narrow available widths and dynamic result insertion/removal. Keep labels readable and the first-result teaser attached to the correct result. Screen readers announce the connection requirement; decorative icons do not add keyboard stops.
- Confirm that SE Traffic, standard result metrics, AI Overview cards and SERP/AI-source CSV exports are unchanged. Lock icons are presentation only, never metric or export values.
- Verify that the existing Connect CTA still works. If the connection-flow ticket ships in the same package, run its cancellation, retry and successful-connection checks too.
Acceptance: Verify the rebuilt extension across disconnected and connected states. Disconnected placeholder zeros become locks; all connected-value formatting remains unchanged, including Authority Score 0 and the existing traffic n/a behavior. This ticket does not claim a measured conversion increase.
Disconnected status cannot start a connection Completed · 4.3.1
Verified: Beatus confirmed that the connected header control opens Integrations across the tested surfaces. Disconnected authorization also passed.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: Quick View, Full Report and Settings show “Disconnected from Semrush” in the header, but the status is a static element (SemrushStatus.tsx). Users who notice it have to find a Connect button elsewhere. The status is the one connection cue that appears on every surface.
Fix:
- Make the header status a button. While disconnected, it starts the direct OAuth flow from the connection-flow ticket, using the same handler and duplicate-start guard. While connected, it opens Settings → Integrations, the same destination as the Settings menu’s Manage Semrush connection row.
- Keep the dot, label and header layout. The pause switch and Settings button keep their positions.
- Show that it is interactive on the dark header: pointer cursor, mint #18F0BF text on hover and keyboard focus like the other header controls, and a visible focus ring. Add the tooltip “Connect your free Semrush account” while disconnected and “Manage Semrush connection” while connected.
- Use the accessible names “Connect to Semrush” and “Manage Semrush connection”, matching the Settings menu. Where the label is hidden at narrow widths, keep the dot inside a padded button with the same accessible name. Match the other header controls’ hit area; do not make the 6px dot the entire click target.
Scope: The header status only. If the connection-flow ticket does not ship in the same package, the disconnected status opens Settings → Integrations instead, like today’s Connect paths. Add no UTMs to the OAuth URL.
Files: src/components/shared/layout/header/SemrushStatus.tsx; src/components/shared/layout/Header.tsx; src/hooks/useSemrushConnection.ts. Reference: src/components/shared/layout/header/SettingsButton.tsx.
Engineering checks
- In Quick View, Full Report and Settings, click and keyboard-activate the status in both states. With the connection-flow ticket included, disconnected starts authorization once; connected opens Settings → Integrations.
- If the connection-flow ticket ships separately, verify that the disconnected status opens Settings → Integrations and its existing Connect control still starts authorization. On the Settings surface, open Integrations within Settings.
- Repeated clicks and Enter presses during authorization do not open a second authorization tab. Cancellation and failure leave the status usable. A successful connection updates the label and dot without a reload.
- Check hover, focus and tooltip on the dark header and at narrow widths. Click the padding around the dot as well as the dot itself; the full button remains usable when the label is hidden. The status does not shift the pause switch or Settings button.
- If analytics can record connection entry points, record this one separately from the connection cards. A click is not a completed connection.
Acceptance: Verify on the rebuilt extension with the real authorization journey. No conversion lift is claimed by this handoff.
Unique Visitors opens Traffic Analytics without the domain Completed · 4.3.1
Verified: The reviewed package generates the current-domain Traffic Analytics destination and preserves Unique Visitors tracking.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: In Full Report → Semrush → Traffic Analytics, Monthly Visits opens Traffic Analytics for the current domain, but Unique Visitors opens the generic https://www.semrush.com/analytics/traffic/ landing (TrafficAnalytics.tsx, trafficAnalyticsBaseUrl). Users who click Unique Visitors have to enter the domain again.
Fix:
- Link Unique Visitors to
trafficFullReportUrl(domain), the same/analytics/traffic/overview/?q=<domain>destination as Monthly Visits. Its overview page leads with Unique Visitors. - Keep
metricTracking('traffic_analytics', 'unique_visitors'), so the link keepsutm_content=semrush_metric_unique_visitorsand stays distinguishable from Monthly Visits. - Leave
trafficAnalyticsBaseUrlfor its other, non-domain uses.
Scope: The Unique Visitors card in Full Report only. Quick View’s Traffic Analytics cards open Full Report and are unchanged. Context: report_traffic_analytics, which covers both links, recorded 192 visits and 7 registrations from August 10 to October 4, 2026; the data does not split by utm_content.
Files: src/components/report/panels/semrush/TrafficAnalytics.tsx. Reference: src/utils/semrush-connected/deepLinks.ts.
Engineering checks
- Unique Visitors opens
https://www.semrush.com/analytics/traffic/overview/?q=<domain>&utm_source=seoquake&utm_medium=toolbar&utm_campaign=report_traffic_analytics&utm_content=semrush_metric_unique_visitors&ref=174537735, with the same domain as Monthly Visits. - Check a root domain, a
www.host and a subdomain. Both cards resolve the same domain. - Monthly Visits and the other Traffic Analytics cards are unchanged.
Acceptance: Verify the final generated URL on the rebuilt extension.
Disconnected Backlinks CTA drops the current domain Completed · 4.3.1
Verified: Beatus’s October 26 live test preserved backlinko.com through the sign-in gate. The domain destination matches the approved requirement. New-account registration was not separately tested. The exact-page destination revision is also complete, following the October 27 live review.
Original requirements and engineering checks
Reviewed 4.3.1 chrome-2-perf · Closed October 26, 2026
Issue: In Full Report → Links, the connected Backlinks CTA opens the current domain’s Backlinks report (/analytics/backlinks/overview/?q=<domain>&searchType=domain), while the disconnected CTA opens the generic /analytics/backlinks (LinksPanel.tsx). Disconnected users lose the site they were analyzing.
Fix:
- Point the disconnected CTA to the same domain-specific destination as the connected CTA. Encode the domain.
- Keep its tracking (
ctaConnectionTracking('backlink_analytics', false)), so connected and disconnected clicks stay distinguishable. - Ship only if the journey check below passes. If Semrush drops
qduring signup or sign-in, keep the current link.
Journey check: In a signed-out browser, open the proposed URL, create a free account, and sign in with an existing account. Both paths should end on the Backlinks report for that domain.
Scope: The disconnected Links CTA only. The connected destination and its tracking are unchanged; choosing a different Backlinks report is a separate decision. Context: report_backlink_analytics recorded 1,350 visits and 49 registrations from August 10 to October 4, 2026, for both states combined.
Files: src/components/report/panels/LinksPanel.tsx.
Engineering checks
- Disconnected and connected CTAs both open the current domain, with their existing
report_backlink_analyticstracking and connection state inutm_content. - Check a root domain, a
www.host, a subdomain and an internationalized domain. The domain matches the connected CTA. - Record the journey check result (new account and existing account) with the change.
Acceptance: Verify the generated URLs on the rebuilt extension and the signed-out journey on semrush.com.
Technical fixes
Implemented. See each item’s verification and remaining checks. The original diagnosis and guidance are kept as history.
Quick View report shortcuts and count fit Completed · 4.3.0
Shipped in 4.3.0: separate Internal/External counts, Words routing, the Full Report menu and the count-fit change. The Words hover/focus descriptions were accepted as unnecessary and are not open work. The combined-large-count limit remains accepted. Earlier screenshots and comparisons below are retained as references, not current defects.
Earlier follow-up requirements · superseded
Implemented in chrome-4: Internal/External occurrence counts and destinations, clickable Words in Page Info and Content, and the Full Report sections dropdown. Loaded-extension checks confirm the four tile routes, report reuse, menu coordination and focus restoration. The original navigation implementation is complete; the two follow-ups below remain.
Issue: Both Words tiles lack a hover/focus description of their Keyword Density destination. Page Info’s seven-column strip also truncates larger values: 10,028 displays as 10,0… at native popup size, while Content shows the full count.
Fix:
- In
PageSummary.tsxandContentSummary.tsx, addbuttonTooltip: 'Open Keyword Density'to thewordsitem. ReuseBoxValue’s existing button tooltip; preserve the blue value, full-tile action andopenReportFromPopup(reportSourceTabId, 'density')routing. - In
PageSummary.tsx, replacegrid-cols-7withgrid-cols-[repeat(7,minmax(max-content,1fr))]and change the strip’svalueClassNamefromblock w-max max-w-[calc(100%+12px)] truncate text-lefttoblock text-left. Columns share the available space until a label or value needs more room. Keep the16pxtile padding, typography, dividers and full-tile actions; Content’s five-column layout stays unchanged. Do not add ellipses or abbreviate counts.
Known limit: Combined large counts—for example, multiple four- or five-digit counts alongside six-digit Words—can exceed the available width. This limit is accepted for 4.3.0; no compact fallback is planned.
Files: src/components/popup/panels/page-info/PageSummary.tsx, src/components/popup/panels/content/ContentSummary.tsx. Reference: src/components/shared/box/BoxValue.tsx and src/utils/surface/navigation.ts.
Engineering checks
- Words tooltip: both callers omit the packaged
buttonTooltipstring prop. Supply the same exact copy to both. Verify hover and keyboard focus, a resolvingaria-describedby, existing tooltip placement/dismissal, and no added info icon or tab stop. - Count fit: Keep the change local to
PageSummary.tsx; preserve sharedBoxValuedefaults,divide-x!,divide-gray-light,px-4padding and20pxvalues. In the supplied extension,10,028needs 70px while its current button has 67px available. Confirm the new arbitrary grid class is generated in the rebuilt stylesheet. - Values: At the native
640 × 600pxpopup, check Words at0,4,204,9,999,10,028,99,999,100,000,999,999and1,234,567, with the other counts held at the reference values. Also check Internal, External and Images counts in the thousands. Within the available width, require complete formatted values, accurate accessible names, no ellipsis or divider overlap, aligned left edges and unchanged data, formatting and scan behavior. - Combined counts and display settings: record where multiple large counts exceed the strip’s available width; this is the accepted limit above, not a guaranteed fit. Check the rebuilt native popup at 125% and 150% zoom, with a larger Chrome minimum font size, and on Windows. A 589px mock strip only simulates reduced width; it does not verify Windows or browser zoom. Keep Content’s existing layout and routing intact.
- Routing regression: click and keyboard-activate Words in Page Info and Content; both open Keyword Density for the same source tab and reuse the existing report. Preserve Internal/External count parity and targets, Images/H1–H4 actions, menu coordination, focus restoration and empty-state behavior.
- Settings: keep the Full Report list separator-free; use the Settings follow-up for its two group separators and 8px header gap. No shared dropdown or permission changes are needed.
Evidence: routing and count clipping were checked in the exact supplied chrome-4 extension using controlled page data. Complete native count captures below show the stored number is correct. Earlier fixture-only and retained inactive-panel measurements are not the basis for this finding.
Count clipping screenshots
Controlled page data, exact supplied package, native 640px viewport. No live Semrush scan.
Proposed count fit · 5, 6 and 7 digits
Current / Proposed design references. Only Words changes; the other counts stay fixed. Each view uses a native 640 × 600px frame, scaled to fit. These previews do not verify the rebuilt extension.
5 digits · 10,028 words
6 digits · 123,456 words
7 digits · 1,234,567 words
Interactive previews
Earlier Before / Proposed references. Try the implemented link counts, Words routing and Full Report menu; proposed Settings shows the remaining grouping and 8px-position fixes. Actions are simulated; nothing is saved. The proposed header includes the Pause controls.
Counts strip
Full Report sections
Open the interactive comparison · Full 640 × 600 previews, scaled to fit.
Screenshots




Original proposal screenshots retained for reference; the interactive previews above show the latest Settings grouping. Renderings are design references, not proof of implementation.
Original implementation requirements · reference
Earlier requirements retained as history. The remaining Fix and Engineering checks above define the current work.
Issue: Quick View combines Internal and External links into one count, Words has no action in Page Info or Content, and Compare has no direct shortcut. Legacy users previously reached these reports from the popup’s top navigation.
Fix:
- In
PageSummary.tsx, replacelinkswith Internal and External. UsepageData.links.filter(link => link.internal).lengthandpageData.links.filter(link => !link.internal).lengthso counts match the report’s total occurrences. Route them throughopenReportFromPopup(reportSourceTabId, 'links', 'internal')and the corresponding'external'call. - In
PageSummary.tsxandContentSummary.tsx, addbutton: { onClick: () => openReportFromPopup(reportSourceTabId, 'density') }towords, reusingBoxValue’s blue value and full-tile action. Usegrid-cols-7in Page Info; keep Content’sgrid-cols-5. Preserve Images and H1–H4 destinations. - In
NavButton.tsx, add a separate chevron beside View Full Report, gated toisPopup. ReuseDropdownwithpanelTitle="Full Report", its existingaria-haspopup="dialog"/role="dialog"semantics, and ordinary navigation buttons. UseREPORT_PANEL_IDSin order with the report’s icons; each row callsopenReportFromPopup(reportSourceTabId, panelId). Keep rows label-only and separator-free; omitdivide-y/divide-gray-lightfrom the report list. - Preserve the label’s
getReportTargetFromPopupTab(currentPanelId)routing and Header’s!isEmptyStatevisibility condition. Coordinate dropdown state throughopen/onOpenChangeso Settings and Full Report cannot remain open together. Move focus into the dropdown on opening and return it to the chevron on Escape or Close; keep the shared dropdown’s other callers unchanged.
Files: src/components/popup/panels/page-info/PageSummary.tsx, src/components/popup/panels/content/ContentSummary.tsx, src/components/shared/layout/header/NavButton.tsx, Header.tsx, SettingsButton.tsx and src/components/shared/Dropdown.tsx. Reference: src/utils/surface/navigation.ts.
Engineering checks
Package grounding: the chrome-3 PageSummary uses links.length, six columns and a noninteractive Words value. LinksPanel already accepts internal / external section targets on initial load and through its section watcher. Its Total sums occurrences; Unique counts grouped URLs. The shared Dropdown already supports controlled open / onOpenChange, outside-click dismissal and Escape, but does not supply initial-focus movement or focus restoration.
- Counts: reuse the collected
internalflag; do not reclassify URLs or count deduplicated rows. Internal + External must equal the old Links count and each report tab’s Total, including duplicate URLs. Check zero links, all-internal, all-external and mixed pages. Use existing formatting and data-loading behavior; no extra scan, API request or permission is needed. - Destinations: Internal opens
('links', 'internal'), External opens('links', 'external'), and Words in both Page Info and Content opens('density'). Images keeps('audit', 'images'); Page Info’s H1–H3 and Content’s H1–H4 keep('audit', 'heading-structure'). RetainreportSourceTabIdand existing report-tab reuse. Check a new report and an existing report on either Links subtab, plus multiple source pages/windows. - Words consistency: verify both
PageSummary.tsxandContentSummary.tsxusewords.total, the sameopenReportFromPopup(reportSourceTabId, 'density')action andBoxValuebutton behavior. In both tabs, the full tile is clickable, the value is blue, Enter/Space activates it, keyboard focus is visible and the hover/focus description names Keyword Density. Test zero and large word counts, then a new and reused Full Report. Reuse collected data; no new scan, request or permission. - Main label: preserve the existing handler. Quick View Audit opens Audit; Schema opens Audit’s
schemasection; Semrush opens Semrush; Page Info and Content use the existing default. Do not replace this with an always-Page-Info callback. Dropdown rows targetpage-info,audit,density,links,compareandsemrush. - Layout: rebuild and verify
grid-cols-7is generated; it is absent from chrome-3’s current stylesheet. Keep Page Info’s seven columns and Content’s existing five columns (H1, H2, H3, H4, Words). Keep the 640px popup, current tile fonts, padding, dividers and hit areas. Check large formatted counts, zoom and no clipped labels/values. Keep short visible labels Internal / External, full accessible names with counts, and a hover/focus description for Words’ Keyword Density destination. - Dropdown: Header owns one active-menu state, passed to the report trigger and Settings through controlled props. The existing props coordinate visibility only; implement focus behavior as an opt-in for this popup flow. Keep the trigger’s accessible name Full Report sections, correct
aria-expanded/aria-controls, a labelled nonmodal dialog and ordinary buttons. Do not addmenu/menuitemroles without implementing the corresponding keyboard model. - Separators: Full Report has no row dividers. Remove list divider utilities rather than masking them with
.sqs-row { border: 0 }. Settings uses the Pause ticket’s three groups, with separators only after Enable SEOquake and the display toggles. Check both menus, connected/disconnected labels and paused Settings; any wrapper change must preserve descendant click handlers, row height and focus styling. - Keyboard: Enter/Space opens the dialog and focuses its first destination. Tab/Shift+Tab reach every destination and Close with a visible indicator. Escape and Close restore focus to the report chevron; outside-click dismissal preserves focus on the clicked control. Choosing a destination uses the existing report-opening flow. Opening Settings closes the report dialog and vice versa.
- Scope and Pause: gate the new control to popup; retain empty/paused/unsupported visibility and valid source-tab handling. Test connected and disconnected Semrush headers alongside the Pause switch, including pausing while a dropdown is open. Keep the header, menu and notice within the popup; preserve the existing Full Report/Settings header behavior and other Dropdown callers.
- Permissions: reuse current collected data and report messaging. No new Chrome extension permissions or permission prompts are required.
Design reference: copied from Opus’s October 13 chrome-2 renderings with frozen page data (123 Internal + 11 External = 134). Chrome-3’s completed fixes are tracked separately.
Verification boundary: the bundled routing and shared components support this approach. The interactive copies demonstrate the design with simulated actions; rebuilt-extension routing, keyboard and state checks are required before closing the ticket.
Quick View pause and Settings layout Completed · 4.3.0
Shipped in 4.3.0: Pause/Resume, Settings grouping and the 8px header gap. The current What’s New spacing is accepted; no padding revert is planned. Earlier screenshots and previews below are retained as references, not current defects.
Earlier follow-up requirements · superseded
Implemented in chrome-4: Header switch, Settings Enable checkbox, shared Pause/Resume state, pending guard, confirmed-state reconciliation and persistent retry feedback. Tested loaded-extension flows cover successful and failed saves, retry, repeated activations, preserved display-toggle values and loading failure. Settings spacing and What’s New dismissal work; only the design follow-ups below remain.
Issue: Settings still separates Preferences, Semrush connection and About with individual lines. Its panel starts 16px below the header, while Full Report starts 8px below it.
Fix:
- In
SettingsButton.tsx, wrap the popup’s Preferences, Semrush connection and About SEOquake in one navigation group. Keepdivide-yon the three-group container only: Enable SEOquake; Show SEObar / Show SERP Overlay; navigation. Keep the outer border and exactly two group separators. - Set the popup Settings panel to an
8pxgap below the header, matching Full Report. Replace its scopedmt-4panel override withmt-2, and verify the final geometry. Keep horizontal alignment,16pxpadding, the12pxtitle gap and34pxnavigation rows.
Files: src/components/shared/layout/header/SettingsButton.tsx. Reference: src/components/shared/Dropdown.tsx. Gate spacing changes to popup Settings; preserve Full Report/Settings surfaces and other dropdown callers.
Engineering checks
- Groups: the packaged
divide-ylist has five direct children, producing four separators. Group the three navigation links as one child without innerdivide-y; retain the outer card border and two group lines. Preserve 34px row heights, full-row checkbox targets, descendant click handlers and hover/focus styles. - Position: at native 640px, the measured header bottom is
48px; Settings starts at64px, Full Report at56px. Settings must also start at56px. Measure the final effective gap after wrapper and panel margins; do not add another 8px to an existing wrapper offset. - States: check connected/disconnected Semrush labels, enabled/paused Settings, and menus with/without What’s New. The top gap stays 8px and the panel stays below the header and within the popup. It overlays the tabs and page content as designed. Preserve the 9px What’s New top padding, 24px column gap, release scrolling and Got it keeping Settings open at single-column width.
- Behavior: Tab/Shift+Tab, Escape/Close, navigation actions, menu mutual exclusion and focus restoration must keep working. Verify Pause/Resume and saved SEObar/SERP choices after regrouping. Preserve existing shared enabled/pending/error handling; no new storage, permissions or page requests.
- Scope: the 8px position is the newly approved design change. Apply it to popup Settings only; preserve the Full Report menu and every other
Dropdowncaller, including Add/Hide Parameters.
Release validation: live Google/account states, all Full Report failure paths, restart/upgrade persistence and assistive-technology announcements remain separate release checks. The review found no additional demonstrated Pause save defect.
Current chrome-4 screenshots
Earlier native Before / Proposed references. Pause controls are implemented in chrome-4; proposed Settings now shows the remaining two group separators and 8px header gap. Controls are simulated and do not change extension preferences.
Quick View header
Settings open
Settings open, with What’s New after an update
Paused
Legacy 3.13.5 reference
Supplied screenshots of the legacy popup: the green on/off switch beside Settings, and Enable SEOquake at the top of its settings menu.


Original implementation requirements · reference
Earlier requirements retained as history. The remaining Fix and Engineering checks above define the current work.
Issue: Pausing requires opening Settings → Preferences → General. Quick View’s Settings menu only offers separate SEObar and SERP Overlay controls, making the global pause setting harder to find.
Fix:
- Add a popup-only switch between the Semrush status and Settings, with a
36 × 32pxhit area. Use mint#18F0BFwith a dark#181E15knob when enabled, and grey#60636Bwith a white knob when paused. Keep the accessible name Enable SEOquake, updatearia-checked, and show Pause SEOquake or Resume SEOquake on hover and focus. - Add Enable SEOquake as the first Settings checkbox, in its own group above the two display toggles. Make each checkbox’s full row clickable. Use
16pxpanel padding,12pxbelow the title and34pxnavigation rows. InSettingsButton.tsx, group Preferences, Semrush connection and About SEOquake in one wrapper; usedivide-ybetween groups only. Keep these changes local to this menu. - Give What’s New a plain wrapper with
9pxtop padding and a24pxgap from the menu box. Align its heading with the first menu row and use the approved 4.3.0 copy. Preserve scrolling; Got it dismisses the notes while keeping Settings open at its single-column width. - Share enabled, pending and error state across the switch, Settings checkbox and existing Resume button. Save only
general.enabled, keep the controls synchronized and prevent stale reads from restoring an older state. Disable pause controls during loading or saving; keep them disabled if loading fails. - On a failed save, restore the confirmed state and show “Couldn’t pause SEOquake.” or “Couldn’t resume SEOquake.” with Try again below the header. Keep the notice visible across normal and paused states. Apply failure reconciliation to Full Report’s existing Pause/Resume too.
- Keep the existing paused screen and Settings access. Preserve saved SEObar/SERP choices, disabling their controls during saving and while paused. Keep native navigation, Settings positioning and empty-state behavior; shift the Semrush status
48pxleft. Full Report and Settings headers stay unchanged.
Engineering checks
Supporting evidence: Quick View’s Settings → Preferences opens Settings → General → Pause SEOquake, which is also available from Full Report. In the uninstall survey (1,301 answers, September 28 to October 13), “I couldn’t find how to turn it off” is the most chosen follow-up for “got in the way”: 61 of 138 answers. Legacy 3.x had an on/off switch in the popup header and an Enable SEOquake option in its settings menu.
Implementation requirements
- Add a switch to the Quick View header, between the Semrush status and Settings, with a 36 × 32px hit area aligned to the Settings button. On uses a mint
#18F0BFtrack with a#181E15knob; paused uses a#60636Btrack with a white knob. Expose it asrole="switch"with the constant accessible name Enable SEOquake andaria-checkedreflecting the enabled state. Show Pause SEOquake or Resume SEOquake on hover and focus, usingInfoTooltipBubblewith the button ref; the defaultTooltiprenders its own info icon and cannot wrap the switch. Use the mint focus ring. - Add Enable SEOquake as the first row of the Quick View Settings menu, in its own group above Show SEObar and Show SERP Overlay. Reuse the existing checkbox. Keep three direct groups under the menu’s
divide-ycontainer: Enable SEOquake; Show SEObar / Show SERP Overlay; Preferences / Semrush connection / About SEOquake. The navigation wrapper has nodivide-y; keep the outer border and separators between groups only. - Tighten the Settings menu to the 4.3 rhythm: 16px panel padding on every side (was 24px top and bottom), 12px below the Settings title (was 20px) and 34px menu rows (8px top and bottom, was 16px). Apply these to the Settings menu only; the shared dropdown panel keeps its spacing elsewhere, including Add/Hide Parameters.
- Make each checkbox row the click target. Move the row spacing into the label, so Enable SEOquake, Show SEObar and Show SERP Overlay are clickable across the full row (30 to 33px tall, was 17px).
- When What’s New shows, replace its inner
Boxwith a plain wrapper: no border or background, no inherited Box padding, 9px top padding and 24px from the menu box, with WHAT’S NEW aligned to the first menu row. Keep the existing release-list scrolling and empty-state height limits. Use the approved 4.3.0 What’s New copy. Got it keeps today’s behavior: What’s New disappears and the menu stays open at its single-column width. - Use one popup controller for enabled, pending and error state, shared by the header switch, Settings row and paused-screen Resume. Save only
general.enabledthroughsaveEnabled/saveSeoquakeEnabled. The popup controls share the same displayed state; Full Report and other open surfaces synchronize when storage commits. The existing hook updates optimistically without rollback; add failure reconciliation with confirmed storage and prevent older refreshes from overwriting a newer accepted action. Guard the enabled-status watcher inusePageDatatoo, so an older read cannot restore the wrong normal/paused body; preserve existing page-loading behavior. - Render the switch while settings load, disabled with loading feedback. Keep it disabled if settings fail to load. Guard all three popup pause entry points while a save is pending; repeated activations during that save are ignored, so the final state is the last accepted action. Show pending feedback and disable the SEObar/SERP toggles during the pause transition.
- Catch failed Pause and Resume saves, including the existing paused-screen Resume. Restore the confirmed enabled state and show a persistent
Noticebelow the header, outside the dropdown and normal/paused content. Use “Couldn’t pause SEOquake.” or “Couldn’t resume SEOquake.” with an actionable Try again control that retries the failed action once saving is available. Keep the notice through popup state changes; show no success notice. Apply failure reconciliation to both Full Report paths: Settings → General viasaveEnabled, and paused-screen Resume viausePageData/saveSeoquakeEnabled. - Pausing shows the existing paused Quick View: “SEOquake is paused” with Resume SEOquake. Keep Show SEObar and Show SERP Overlay at their saved values but disabled while paused, so resuming restores the previous setup.
- Gate the new switch to
surface === 'popup'in the shared Header and render it independently ofisEmptyState. Keep the native left navigation and Settings button in place; the Semrush status shifts 48px left to make room. The paused and unsupported states keep their existing hidden View Full Report behavior. Settings remains usable while paused. Full Report and Settings headers do not change.
Package evidence: in the supplied 4.3.0 package, the Quick View header has the Semrush status and Settings only. The Settings menu lists Show SEObar, Show SERP Overlay, Preferences, Connect to Semrush (Manage Semrush connection when connected) and About SEOquake. Pausing from Full Report → Settings → General shows “SEOquake is now paused.” and the paused Quick View. The comparisons reuse that rendered markup; they are appearance references, not a rebuilt extension.
Verification
- Pause and resume through the header switch, Enable SEOquake row, Quick View’s paused-screen Resume, Full Report → Settings → General and Full Report’s paused-screen Resume. All popup controls share state; other surfaces agree after the write commits. Verify persisted state after reopening Quick View, page reload and browser restart.
- Pausing stops the same surfaces as the existing global pause, in every open tab. Resume restores the saved SEObar and SERP Overlay choices. Settings remains openable while paused, with Enable SEOquake unchecked and the saved surface toggles disabled.
- Force settings loading, a load failure and a slow save. The switch stays visible; saving is unavailable until settings load successfully. All popup pause controls are guarded during a pending write. Rapid activations cannot enqueue conflicting actions; the last accepted action wins.
- Force failed Pause/Resume saves from each popup entry point and Full Report → Settings → General, plus a failed Resume from Full Report’s paused screen. The displayed state reconciles with confirmed storage. The popup error notice stays visible outside the menu and changing page content; Try again retries the failed action. Delay older settings and page-status refreshes while accepting a newer action; verify neither the controls nor the normal/paused body can revert to stale state.
- Keyboard: Tab reaches the switch before Settings; Space and Enter activate it once. A screen reader announces Enable SEOquake with the changing on/off state. Check loading/pending feedback, the mint focus ring and the Pause/Resume tooltip on hover and focus.
- At 640px, check connected/disconnected status, Settings with and without What’s New, paused and unsupported states. Nothing wraps or overlaps. View Full Report stays hidden in empty states. Full Report and Settings headers are unchanged.
- Measure the revised menu height at 640px with and without What’s New; confirm it fits the popup. Keep navigation rows at 34px when removing their borders. Verify exactly two group separators, no lines between the three navigation links, and unchanged hover/focus, Tab order and link actions in connected/disconnected and enabled/paused states. Every checkbox label is a full-row target. Got it removes What’s New and leaves the menu open at its single-column width. Check longer or multiple unseen releases with the existing scroll limits. Rebuild and verify the scoped spacing utilities; Add/Hide Parameters and other dropdowns are unchanged.
Files: src/components/popup/PopupApp.tsx (shared popup pause controller and persistent error notice), src/components/shared/layout/Header.tsx (popup-only switch), a new src/components/shared/layout/header/PauseSwitch.tsx, src/components/shared/layout/header/SettingsButton.tsx (shared pause handler, menu row and scoped spacing), src/components/shared/form/Checkbox.tsx (optional label className), src/hooks/useAppSettings.ts (save reconciliation and stale-refresh protection), src/components/shared/PageAnalysisState.tsx (Resume busy state), src/hooks/usePageData.ts (caught Resume handling and enabled-status refresh ordering) and src/components/settings/panels/GeneralPanel.tsx (verify reconciled Full Report Pause/Resume). References: src/utils/settings/storage.ts, src/utils/settings/messaging/handlers.ts, src/components/shared/Notice.tsx, src/components/shared/Tooltip.tsx (InfoTooltipBubble) and src/components/shared/layout/header/ReleaseNotePanel.tsx. Reuse the existing preference and pause consumers.
SERP script loads on every website Implemented · 4.2.1 chrome-3
Verified Sep 24: Robert’s ai branch scopes the SERP script with includeGlobs. On a regular site it no longer loads: 105 ms script time and 3.2 MB JavaScript heap at 4x CPU, the same as 4.1.1.
Issue: 4.2.0 loads the SERP Overlay script and styles (serp.js, serp.css) on every website, next to content.js and seobar.js. That is about 1.6 MB per page, against 0.4 MB in 4.1.1. The SERP code only acts on Google, but Chrome reads and prepares it on every page before that check runs. The 4.2.1 build from the ai branch still loads it everywhere, and the AI Overview panel makes it heavier:
| Build | Loaded on every website |
|---|---|
| 4.1.1 | 408 KB |
| 4.2.0, live | 1,646 KB |
4.2.1, ai branch package chrome-2 | 1,952 KB |
Measured on 10 regular websites with the CPU slowed 4×, close to a budget laptop:
| Build | Script time per page | JavaScript heap per page |
|---|---|---|
| 4.1.1 | 99 ms | 3.1 MB |
| 4.2.0 as shipped | 188 ms | 5.2 MB |
| 4.2.0 with this fix | 105 ms | 3.2 MB |
Fix: Load the SERP content script only on Google. In src/entrypoints/serp.content.tsx, add include globs. WXT then writes a separate manifest entry for the SERP files:
export default defineContentScript({
matches: ['<all_urls>'],
includeGlobs: ['*://www.google.*/*', '*://google.*/*'],
cssInjectionMode: 'manifest',
runAt: 'document_idle',
...
- Match patterns can’t use a wildcard for the domain ending, so
*.google.*is invalid inmatches. Include globs allow it, which covers Google’s country domains. - Cover all Google pages, not only
/search, so the script is already present when results load without a full page navigation from the homepage. - Keep the runtime Google check. The globs decide where Chrome loads the script; the code decides where it acts. See the Google host check below.
- No permission change. Host access stays on all sites for SEObar and the popup, and Chrome only prompts users when an update adds access.
Verified on a hand-edited copy of the chrome-3 manifest: the SERP script no longer loads on regular sites. It still loads on google.com, google.co.in, google.de and the Google homepage, and the sidebar appears on results pages. Confirm the WXT build emits the same shape: an <all_urls> entry with content.js and seobar.js, and a second entry with serp.js, serp.css and include_globs.
Retest on the 4.2.1 build: the overlay and the AI Overview panel on google.com, a country domain and incognito; after Set locale; after searching from the Google homepage; SEObar on regular sites and still off Google. Download the check script. It reports which SEOquake scripts load on each test address and the script time per page.
No uninstall feedback Implemented · 4.2.1 chrome-3
Verified Sep 24: setUninstallURL points at the Google Form in chrome-3. Code verified; the manual remove-and-check test is still to run.
Issue: Weekday uninstalls rose from 1,061 before launch to 1,635 on September 14–15 and 1,951 on September 21. Neither legacy nor v4 sets an uninstall page, so there is no direct way to learn why.
Fix: Set an uninstall page when the background service worker starts. Chrome opens it in a new tab after someone removes SEOquake. It needs no permission, and the URL can be up to 1,023 characters. The form is live, and the version field fills in from the URL:
const UNINSTALL_FORM_URL =
'https://docs.google.com/forms/d/e/1FAIpQLScp-KrstuXiG74yLkPZx4j5yAprdDdXoh3cqrPCq3YoItNGBA/viewform?usp=pp_url';
const VERSION_FIELD = 'entry.566287330';
browser.runtime.setUninstallURL(
`${UNINSTALL_FORM_URL}&${VERSION_FIELD}=${encodeURIComponent(browser.runtime.getManifest().version)}`
);
- Pass only the version, nothing that identifies the user. Open the form with 4.2.0 filled in.
- Verified September 22: the form opens without sign-in, and the version field shows the value from the URL.
- Form content, for reference: one required question, “Why did you remove SEOquake?”, with seven reasons in shuffled order plus Other. Then an optional “Anything else we should know?” and the version field. No email is collected.
- Mention the uninstall page in the privacy policy.
Retest: in a test profile, remove SEOquake. Chrome should open the form in a new tab with the installed version filled in. Delete the test response afterward.
AI Overview panel adds a duplicate stylesheet Implemented · 4.2.1 chrome-3
Verified Sep 24: One stylesheet copy in the AI panel. serp.js is 944 KB, down from 1,384 KB.
Issue: On the ai branch, src/utils/serp/google/ai/controller.ts imports serp-ai.css?inline, and that file imports all of Tailwind. The SERP script now carries a third full copy of the stylesheet, about 215 KB. Until the SERP script scope fix ships, that copy loads on every website.
Fix: Style the AI panel with the stylesheet the overlay already carries. Both existing copies in the 4.2.1 package include every utility class the panel uses. From serp-ai.css, keep only the rules the shared stylesheet lacks: the :host block and the .ai-compact-tight padding rule. Drop its Tailwind and base imports.
Retest: serp.js shrinks by about 215 KB. The Analyze sources button, the panel and the strips on source cards look identical to the chrome-2 package, in light and dark mode and in a narrow window.
Analyze always opens the US database Implemented · 4.2.1 chrome-4
Verified Sep 24: commit 9c2927a adds databaseCountry.ts and follows the country order below. The SERP Analyze button, the Rank, Traffic and Costs links, the AI Overview panel and Quick View pass the country. All original retest cases passed against the committed code, and the chrome-4 build has no hard-coded db=us left.
Issue: src/utils/semrush/overviewLinks.ts hard-codes db=us (line 9), so every caller opens Domain Overview on the US database, even when Locale is set to another country. Reported by a user: a .nl domain that barely ranks in the US opened an empty-looking report until they switched countries manually. Legacy never set db on these links; v4 added the US hard-code. Callers:
SerpAnalyzeCta.tsx: the Analyze CTA in the SERP strip, also used on AI Overview source cards.metricLinks.ts: the Rank, Traffic and Costs links.SemrushOverview.tsx: Quick View.
Fix:
- Add an optional country argument,
domainAnalyticsOverviewUrl(input, country?), and setdbfrom it. - Resolve the country in this order, first match wins:
- The saved SERP Locale country, the one Set locale applies as
gl. - The
glparameter on the current Google URL. - The Google country domain: google.nl is
nl, google.co.uk isuk. google.com gives no signal. - The result domain’s country ending: .nl is
nl, .co.uk isuk. Generic endings like .com give no signal. us.
- The saved SERP Locale country, the one Set locale applies as
- Map Google and ISO codes to Semrush database codes. Most match in lowercase; the United Kingdom is
ukin Semrush,gbin Google. - If Semrush has no database for the country, fall back to
us. - Pass the resolved country from the SERP strip, the AI panel and the metric links. Quick View can use step d only.
Out of scope: the Rank, Traffic and Costs values in the strip come from seoquake.publicapi.semrush.com/info.php, which has no country parameter. They stay US figures, and the Traffic tooltip already says US. Only the links change.
Why it matters: Analyze is the top SERP Overlay source of Semrush visitors, and India and Pakistan are the biggest audiences. Local sites analyzed on the US database show thin data at the moment we ask people to register. Compare the serp_domain_overview visit-to-registration rate in Stork before and after.
Opening SEOquake can log you out Implemented · 4.2.2 chrome-5
Implemented in chrome-5. Package checks and the installed WordPress smoke test passed. Controlled browser regression checks remain below.
Original issue: live 4.2.1 automatically checks internal links when Quick View or Full Report opens, using the website’s login cookies. That includes WordPress’s admin-bar Log Out link. The checks send HEAD and fall back to GET. HEAD alone can end the session, so removing the GET fallback won’t fix it.
Introduced in 4.0.0 and still present in live 4.2.1, which is available at 100% rollout.
Verified Sep 30 · chrome-5: the reviewed package implements the image protection, expanded exclusions, Audit safeguards and numeric CSV Status format. Extracted-code checks passed. On a logged-in WordPress site, Quick View, Schema, Full Report and manual link checks preserved the session; fresh reloads stayed logged in. Logout and cache-purge links showed Skipped. Inspected sitemap, link and image requests sent no website Cookie or Authorization headers. A normal public social preview rendered, unchecked/all-skipped Audit results showed warnings, and CSV exports kept numeric codes or n/a.
Earlier chrome-4 result: link checks preserved the synthetic session, but a logout URL used as og:image still sent cookies and ended it. Chrome-5 routes that preview through the protected helper. The hostile-image case still needs controlled browser verification.
Earlier tests: the original 4.2.2 candidate reproduced logout with HEAD alone and HEAD-to-GET fallback. Controlled fixtures also reproduced cache-purge and empty-cart actions.
Implemented in chrome-5
- The shared public-request helper forces
credentials: 'omit'after...initand removes Cookie, Authorization and Proxy-Authorization headers. Deliberate Semrush OAuth authorization stays separate. The social image preview now uses this helper. - Link-status checks no longer start when Quick View or Full Report opens. The shared flow is opt-in, with a Check status button in Links.
- Collected admin-bar links are marked and skipped. The expanded action policy runs in both frontend and background paths before cache lookup, before requests and at redirects.
- Status and cache keys preserve query strings, so
/cart/and/cart/?empty-cart=1cannot share a query-stripped result. - Link responses with 401/403 show warnings and are excluded from Broken totals. Skipped links are neutral in the Links table. Unchecked and all-skipped Audit sets show a warning. Additional inconclusive classifications follow in 4.2.3.
Completed from the chrome-4 review:
- Load the social share preview image (og:image or twitter:image, in Quick View’s Schema tab and the Full Report’s Audit) through the same anonymous helper, apply the same skip rules, and render the returned data URL. Direct
<img src>loads can send the site’s cookies. Show the placeholder when the image is skipped. - The action-URL policy now covers both frontend and background paths, including session and download parameters, names containing nonce or token, and the action words below. Removing cookies alone isn’t enough when the URL carries a session or token. Keep these minimum exclusions:
- WordPress: any path ending in
/wp-login.phpor another/wp-*.phpfile, any path containing/wp-admin/(covers subdirectory and multisite installs), and links inside#wpadminbar, marked when links are collected. - Session and token parameters:
sid,PHPSESSID,jsessionid,osCsid,zenid,key,token,hash,sig,signature,download_file,download_key,eddfile,empty-cart,remove_item, any parameter name containingnonceortoken, and a;jsessionid=path parameter. - Action words: a path segment or parameter value of logout, log-out, logoff, signout, sign-out, unsubscribe, confirm, verify, activate or reset-password. Treat an
actionparameter as an action only when its value is one of these, or when the URL also carries a nonce or token.
- WordPress: any path ending in
- The Audit now requires completed eligible checks before a pass. Unchecked or all-skipped sets show the existing warning state, not a healthy pass. Keep the existing link 401/403 warnings and neutral skipped-link handling. Policy-skipped links stay listed but don’t block a pass when eligible checks are complete. Keep link counts and structural findings available. Genuine 404/410 and server errors still fail.
CSV compatibility: chrome-5 restores the existing numeric Status column, with n/a when no HTTP status is available. The new Check result column is implemented in the 4.2.3 candidate.
Implemented in the 4.2.3 candidate: the link check accuracy update adds the remaining classifications, robots/sitemap warnings, shared controls, labels and CSV column. Package checks passed; installed-browser smoke checks remain. Website checks stay anonymous.
Remaining browser QA: use a controlled fixture for a hostile social-image URL, excluded redirect destinations, forced HEAD-to-GET fallback and Set-Cookie rejection. These were not manufactured on the live WordPress site. Real WordPress deletions remain untested.
Regression checks and test boundaries
The installed WordPress run covers the normal flows above. The full checklist below remains the regression reference; hostile image and redirect cases have extracted-code coverage, not installed-browser proof.
- On staging WordPress with a logged-in admin bar, open Quick View and Full Report, then open Links and press Check status. The user stays logged in and action links show Skipped. Exercise eligible HEAD-success and HEAD-to-GET checks, and confirm excluded action URLs are never requested.
- Network logs show no requests to excluded action URLs, including through redirects. Eligible public checks send no website Cookie or Authorization credentials and don’t apply Set-Cookie responses. Safe public redirects and existing private-address guards still work.
- Opening Quick View, Full Report or its Links tab sends no automatic link-status requests. The Links button starts eligible checks and shares the results with the Audit.
- These links are all Skipped and never requested: a phpBB-style
ucp.php?mode=logout&sid=…, a WooCommercedownload_filelink, an Easy Digital Downloadsdownload_keylink, an uppercase or percent-encoded nonce parameter, and a subdirectory/blog/wp-login.php. - With
/cart/already checked,/cart/?empty-cart=1shows Skipped, not the cached result. - With og:image set to the logout URL, opening the Schema tab and the Audit neither logs the user out nor requests that URL with cookies. Public og:image and twitter:image previews still render.
- Before checking, and with every link Skipped, the Audit shows a warning rather than a healthy pass. Link 401/403 results keep their warnings and stay out of Broken totals. Eligible working links can still pass with skipped admin-bar links present. Real link 404/410 and genuine server-error failures still fail; existing structural findings remain.
- Export before checking and after mixed results. Status keeps numeric HTTP codes or
n/a, without descriptive labels mixed into that column. Unchecked and skipped rows remain exportable without starting checks.
Files: src/utils/network.ts, src/utils/links/status.ts, src/utils/messaging/links.ts, src/utils/links/types.ts (skip reasons), src/hooks/usePageData.ts, src/hooks/useLinkStatuses.ts (cache keys and skipped results), src/utils/page/collectors/links.ts (marks admin-bar links), src/components/shared/schema/SocialSharePreview.tsx, src/utils/page/analyzers/linksInternal.ts (pass safeguards), and src/utils/links/exportCsv.ts (existing Status format).
A number formatter slows every page load Implemented · 4.2.2 chrome-4
Verified Sep 30: chrome-4 creates the integer formatter on first use and reuses it. Extracted checks passed in all four bundled consumers, with unchanged output for eight values each. Fresh page-timing checks remain part of final QA.
Original issue: the earlier 4.2.2 candidate creates its integer formatter (new Intl.NumberFormat) when src/utils/format.ts loads, instead of the first time a number is formatted. The SEObar script runs on every website, so every page pays for it. On local test pages with the CPU slowed 4×, 4.2.2 used about 20 to 30 ms more script time per page than 4.2.1, on regular sites and on Google results. On a normal CPU that is roughly 5 ms per page (an estimate).
Fix: create the formatter on first use.
let integerFormatter: Intl.NumberFormat | undefined;
export const formatInteger = (num: number): string =>
(integerFormatter ??= new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 })).format(num);
Applied to a copy of the 4.2.2 build, this brought regular pages back to 4.2.1’s range in two independent test sessions and reduced the difference on Google results. formatInteger is the formatter’s only consumer, and output is unchanged.
Verify: the formatter isn’t created at load, and integers format the same (12,345). Regular-site script time matches 4.2.1 on the same test pages, with the builds measured in both orders. Report any remaining difference on Google results.
Files: src/utils/format.ts.
4.2.2 What’s New needs clearer copy Implemented · 4.2.2 chrome-5
Verified Sep 30 · chrome-5: the package contains all four approved lines, including the sign-out fix. In the installed Quick View Settings popup, all four lines, View all updates and Got it were visible. Text wraps within the column without being cut off.
Original issue: the popup’s What’s New shows each [+] and [*] line from the 4.2.2 block in CHANGELOG. The earlier candidate said “audit heading detection” for a SERP fix, claimed unmeasured audit performance gains and buried Analyze opening the exact page under “Analyze/Semrush links”. Its fifth line was cut off.
Implemented copy:
================================
Change Notes for SEOquake 4.2.2
================================
Date: 9/30/2026
SEOquake 4.2.2 gives you more control over the SERP Overlay and sharper Semrush links.
[+] Collapse the SERP sidebar to a small tab.
[+] Analyze opens the exact page in Semrush.
[+] Settings now save as you change them.
[*] Fixed a bug where SEOquake could sign you out of your site.
The popup shows the three [+] lines and the [*] line; the parser skips the summary line and section headers. The security fix is implemented in the same package; its remaining controlled browser checks stay part of final release QA. Update the date if the build ships later.
Verify: all four lines are fully visible in the popup, with no text cut off.
Files: CHANGELOG.
Link checks have clear states and labels Implemented · 4.2.3 candidate
Implemented in the 4.2.3 candidate. Package checks confirm shared Check link status buttons in Audit and Links, clear states and matching CSV labels. Installed-browser smoke checks remain.
The new response handling keeps anonymous 401/403/429, login redirects and confirmed bot challenges neutral across the report, robots.txt and sitemap. Unchecked and all-skipped sets cannot pass; genuine failures still fail. The 4.2.2 security protections remain intact.
Implementation reference
Original guidance:
- Finish neutral handling across the Audit, Links table and totals. Keep the existing 401/403 handling and add 429, recognized login redirects and positively identified bot challenges. These results count as neither broken nor healthy. Carry skip or login-redirect reasons and the challenge indicator through response types and hooks. Identify challenges only with supporting evidence, such as
cf-mitigated: challenge, never from a 503 alone. Preserve available HTTP codes. - Apply those rules to robots.txt and sitemap checks. Anonymous 401/403/429 responses, stopped login redirects and confirmed challenges show warnings. Carry the reasons and positive challenge indicators through page-network results. Keep existing missing-file and structural checks, and genuine server-error failures.
- Finish the shared check flow. Keep the existing opt-in behavior and add the trigger on the Audit’s Internal Links row. Label both buttons Check link status and use the same results. Preserve the 4.2.2 neutral classifications and pass safeguards. Finish the Not checked, Checking and Needs review states. Keep link counts and structural findings available. If no links are broken but some couldn’t be checked, show “N links couldn’t be checked.” Policy-skipped links don’t trigger Needs review. Independently verified failures still fail.
- Add clear labels to the 4.2.2 results. Use Authentication required for 401, Couldn’t check (HTTP 403) when the refusal’s cause is unknown, and Rate limited (HTTP 429). A recognized login redirect shows Login required (redirect). Use the existing challenge indicator to label confirmed bot protection. Preserve available HTTP codes and apply the labels consistently in the Audit, Links table and totals. For robots.txt and sitemap 401 or recognized login redirects, add the warning Not public to anonymous visitors (HTTP N). Other inconclusive results keep their matching reason. Genuine server errors remain failures.
- Add the CSV Check result column for the matching label, preserving the numeric Status format restored in 4.2.2. Use
n/awhen no HTTP status is available. Not checked and Skipped rows must remain exportable without starting link-status checks.
Browser checks and files
Remaining installed-browser checks:
- Opening Full Report, or its Links tab, sends no automatic link-status requests. Either button starts the checks and updates both views.
- Unchecked or inconclusive results never produce a healthy-link pass. Inconclusive checks alone show Needs review, rather than “fix broken targets.” Policy-skipped links, including the admin bar, don’t block a pass or trigger Needs review.
- Test working links, 404/410, 401, an unexplained 403, 429, a recognized login redirect, a confirmed challenge and a server error. Labels and totals agree; excluded redirect destinations are never requested.
- Robots.txt and sitemap checks show a warning for anonymous 401/403/429 responses, a stopped login redirect or a confirmed challenge, including a 503 with a positive challenge indicator. A 401 or recognized login redirect uses the Not public warning. An unexplained 503 remains a server error. Existing missing-file and structural findings remain.
- Export before checking and after mixed results. The CSV preserves HTTP codes, carries the matching labels and includes unchecked and skipped rows.
Files: src/utils/network.ts, src/utils/links/status.ts, src/utils/messaging/links.ts, src/utils/links/types.ts (response indicators and UI states), src/utils/messaging/pageNetwork.ts, src/utils/page/collectPageNetworkData.ts (robots and sitemap indicators), src/utils/page/analyzers/linksInternal.ts (classifications and states), src/utils/links/exportCsv.ts (Check result column), src/components/report/panels/LinksPanel.tsx (Audit trigger and shared results), src/components/report/panels/links/LinksTable.tsx and src/components/report/panels/links/LinksOverview.tsx (classifications and labels), src/utils/page/analyzers/robotsTxt.ts and src/utils/page/analyzers/sitemap.ts (warnings), src/hooks/usePageData.ts, src/hooks/useLinkStatuses.ts and the Full Report link-check trigger.
Quick View Settings has a SERP Overlay switch Implemented · 4.2.3 candidate
Implemented in the 4.2.3 candidate. Show SERP Overlay now sits directly below Show SEObar. Package checks passed for saving, sync, rapid changes, preserved preferences and failed-save retry. Installed-browser smoke checks remain.
Browser checks and files
Original issue: turning off the overlay required opening Preferences or using the Google sidebar. The new control uses the same checkbox style and existing serp.enabled preference.
Verify: it toggles the overlay, stays synced and saved, and leaves other preferences unchanged.
- Reuse
serp.enabled. Keep saved metrics, AI-source and sidebar-collapse choices. Disable the control while settings are loading or unreadable; don’t show a failed save as saved. - Check off/on against an open Google results page without reloading, then reopen Quick View and restart Chrome. Changes from the sidebar or full Settings must agree. Rapid SEObar and SERP Overlay changes must both persist.
- Check keyboard access, a failed save and popup fit with and without What’s New.
Files: src/components/shared/layout/header/SettingsButton.tsx, src/hooks/useAppSettings.ts and the existing settings save/watch flow.
Readable result position numbers Implemented · 4.2.3
Implemented: 4.2.3 places numbers beside the title as 3., with inherited typography, legacy float wrapping and the existing preference. Numbers follow Google’s background independently of the selected overlay theme. Package checks covered counting, offsets, dynamic cleanup and CSV positions; the user’s October 12 captures show readable numbers on light and dark Google, including positions 11–15 on the next results page.
Release status: shipped in 4.2.3, with rollout set to 100% on October 12, 2026, at 1:58 PM EDT. The earlier diagnosis and comparison below are retained as history.
1.iPhone
1.iPhone
Historical comparison of the October 7 candidate and accepted number styling, using that candidate’s selected metrics, fonts and title → overlay → snippet order. Metrics are October 7 snapshots; these are rendered references, not October 12 runtime captures. Scroll narrow previews to keep the reference width.
Earlier extension screenshots · October 7


Fix: use #181E15 on light pages and readable light text on dark pages, based on Google’s actual page theme. Keep the title’s font family, size, line height, 0.3em gap and float wrapping. The clickable number should use the title link’s pointer cursor.
Verification and files
Verify: check the number on light and dark Google pages, then toggle numbers off/on; check short and wrapped titles, the next results page and results added or removed dynamically. The number matches the title’s typography and first-line baseline; wrapped lines can use the full title width below it. Numbers agree with the existing result positions and CSV, without duplicates or counting ads/AI source cards. Clicking either the title or number opens the same result; mouse and keyboard navigation stay usable. Check that the screen reader’s link name remains clear. Test on the identified rebuilt extension; this comparison is a mockup.
Files: src/components/serp/overlay/SerpStandardMetrics.tsx, the SERP host mount/update/cleanup flow and Google title placement in src/utils/serp/google/insert.ts. Reuse showPositionNumbers and the existing result position data.
Dark SERP Overlay and theme settings Implemented · 4.2.3
Implemented: 4.2.3 uses SEObar’s dark palette for organic strips, connected metrics, AI source cards and the Analyze sources panel. Full Report → Settings → SERP Overlay → Appearance offers Match Google, Light and Dark. Package review and the user’s October 12 smoke evidence confirmed the dark surfaces and readable result numbers. The sidebar still needs its own application of this shared theme.
Release status: shipped in 4.2.3, with rollout set to 100% on October 12, 2026, at 1:58 PM EDT. The accepted specification and earlier comparison remain below.
Fix:
- Keep the current layout and spacing. In dark mode, use
#2A3028for the connected top row and#181E15for the standard strip and AI cards, with a thin, subtle divider between organic rows. Keep white values and icons, muted labels#A8A9AD, green#18F0BFfor hover and keyboard focus, and light lavender#C190FFfor Analyze and purple accents. - In Full Report → Settings → SERP Overlay → Appearance, add Theme above Show tooltips, using the existing Appearance choice style: Match Google (default), Light, Dark. Save automatically and independently of SEObar. Existing users without a saved choice start on Match Google; Reset restores it.
- Match Google follows Google’s actual page theme and updates when it changes. Light and Dark override the overlay’s appearance. Keep the existing light palette. Position numbers always follow Google’s background, independently of the overlay choice, so they remain readable.
- Apply the same colors to organic strips, connected metrics, AI source cards and the Analyze sources panel, including their tooltips and controls. Keep values, links, preferences, exports and counting intact.
Related: result position numbers are implemented in the same 4.2.3 package and follow Google’s background independently of the overlay choice.
1.iPhone
1.iPhone
Historical reference using the October 7 candidate’s rendered markup, Inter fonts and icons, with Google’s source-card structure, favicons and thumbnails. The accepted treatment changes colors only. Overlay theme previews the implemented setting; it does not save extension preferences. Metrics are October 7 snapshots; these are rendered references, not October 12 runtime captures. Scroll narrow previews to keep the reference width.
Actual extension screenshots
October 7 captures. These are the original images; the comparisons above keep their layout and selected metrics.


Engineering checks
Verify: on light and dark Google pages, test Match Google and both overrides, including a page theme that differs from the computer’s setting. Change Google’s theme without reloading. Confirm numbers remain readable with the opposite overlay theme. Check wrapped titles, connected/disconnected metrics, AI cards, the source panel, tooltips, hover and keyboard focus. Reopen Settings and restart the browser to confirm the saved choice; check the default, Reset and existing autosave failure/retry behavior. SEObar settings, values, destinations and exports remain intact.
Files: reuse SEObar’s existing theme colors in the SERP styles and shared metric components, with the top-row shade specified above. Add the SERP Appearance choice through the existing settings control, preferences defaults/normalization and autosave flow. Apply Google theme detection and the saved override at the SERP host, including its separate shadow roots. Keep title-number contrast tied to Google’s background and preserve its accepted placement and lifecycle.
Report parameters don’t save until you click Save Implemented · 4.3.0 chrome-3
Verified October 13, 2026: Report choices update and save immediately; Save is removed. Package checks cover retry, scoped Reset, stale updates and Compare loading states. Supplied-package review and Beatus’s live review passed for this ticket. Original requirements and references below are retained as history; release QA is tracked separately.
Issue: Add/hide parameters in Full Report’s Links and Compare still requires Save. Closing the menu can leave ticks that don’t match the displayed metrics, and reloading loses those changes. Saving Internal can also discard unsaved External ticks. Settings already saves automatically; these report menus should work the same way.
Fix:
- Update visible metrics and save each tick immediately in Internal Links, External Links and Compare. Remove Save. Closing, reopening and reloading must keep the ticks and displayed metrics in agreement, including changes made from Settings → Parameters.
- Reuse
useSettingsAutosaveforparameters.internal_links,parameters.external_linksandparameters.compare: write changes in order, keep edits when a save fails and offer Try again. An older settings refresh must not overwrite a newer edit. No success notice. - Keep Reset to default and its confirmation. The hook’s current Reset clears its whole pending patch; scope it to the current section and prevent its earlier saves from restoring old values. Preserve pending or failed edits in the other Links tab.
- In Compare, show Run Compare to load in a newly enabled metric’s row only when its data was never requested. Track the domain, backlinks and Pinterest request groups for each result. Preserve already fetched values and keep failed or unavailable results distinct. The next comparison loads enabled metrics; ticking a parameter does not start a request.
Files: src/components/report/panels/LinksPanel.tsx, src/components/report/panels/ComparePanel.tsx, src/utils/compare/buildRows.ts, src/components/shared/ParameterVisibilityDropdown.tsx and src/hooks/useSettingsAutosave.ts.
Engineering checks
Package evidence: the draft/applied split and cross-tab reset are present in the supplied 4.2.3 and 4.3.0 packages. The proposed autosave fix still needs rebuilt-package checks.
- Toggle several parameters quickly, close the menu, switch tabs and reload. The final choice stays applied and stored. A change made from Settings agrees with the report menus.
- Force a save failure, keep editing and retry. Reset Internal while External has a pending or failed edit, then reverse the tabs. Only the reset section returns to defaults; stale writes and refreshes cannot undo either section’s latest choice.
- Run Compare, then enable a metric whose request group was not attempted. Its row shows the load hint until the next run. Also enable a metric from a group already fetched: retain its value. Failed requests and unavailable results must keep their existing states rather than showing the never-requested hint.
Links table is wider than its report card Implemented · 4.3.0 chrome-3
Verified October 13, 2026: Both Anchor Text row types use the approved sizing, with max-w-0 present in the stylesheet. Default Backlinks-only tables fit the reference card; wider metric sets retain scrolling. Supplied-package review and Beatus’s live review passed for this ticket. Original requirements and references below are retained as history; release QA is tracked separately.
Issue: the Links table’s width constraints push columns beyond the card, even with only Backlinks visible. Long check-result labels make it wider. Anchor Text should use the space left by the other columns.
Fix:
- In
LinksTable.tsx, applyw-full max-w-0to both Anchor Text<td>cells, including expanded duplicate rows. Apply these classes only to Anchor Text cells. Removemax-w-80from the inner text span and make it follow the column width. Truncate long text, keep the full text in its hover title and retain the header’smin-w-40(160px) minimum. - Rebuild and verify that the generated stylesheet includes
max-w-0, with its maximum width resolving to0px. The utility is absent from the current package; changing class names against its old stylesheet will not apply the fix. - With only Backlinks visible, fit the table inside the card at the reviewed desktop width, before and after link checks. Keep URL, Follow, Status and Check result readable; do not hide columns to make them fit.
- External defaults and extra metrics may still need horizontal scrolling. Keep every column reachable, with long URLs, anchor text and status labels contained in their cells. Apply the same sizing rules to the 4.3.0 design refresh.
Files: src/components/report/panels/links/LinksTable.tsx.

Engineering checks
Package evidence: controlled rendering confirms overflow in both supplied packages. The proposed 4.3.0 Anchor Text fix fits the reviewed Internal defaults; it does not make External defaults or every metric fit without scrolling.
- Confirm the rebuilt stylesheet emits
max-w-0and both ordinary and expanded duplicate Anchor Text cells compute tomax-width: 0px. - Check both Links tabs with only Backlinks visible at the reviewed 898px inner frame width. Include long anchors, expanded duplicates and long Check result labels. Anchor Text retains at least 160px; the table fits before and after checking.
- Check External defaults, all metrics and narrower windows. Horizontal scrolling reaches the last column without overlapping text. Sorting, links and CSV export retain their existing behaviour and full values.
Global styles override the revised link and heading colors Implemented · 4.3.0 chrome-3
Verified October 13, 2026: Tinted-tip links use #2154CC and Heading Structure level tags use #60636B. Ordinary links retain #2969FF. Supplied-package review and Beatus’s live review passed for this ticket. Original requirements and references below are retained as history; release QA is tracked separately.
Issue: Quick View’s lavender tip bar and the Audit’s blue Tips area use the same bright blue links as white backgrounds. The text has too little contrast. This is present in 4.2.3; the darker link utility added for 4.3.0 is overridden by the global link rule. The global heading rule also overrides Heading Structure’s gray level tags with near-black. Gray tags are an agreed design consistency change; the current near-black tags do not have a contrast failure.
Fix:
- Add
text-blue-dark custom-colorto the actualLinkanchors in bothTipCtabranches inTipBar.tsxand the Tips Link inAuditGroup.tsx. The explicit utility supplies#2154CC;custom-colorexempts these anchors from the global rule that restores#2969FF. - Use
text-gray!on the sharedHeadingStructurelevel tag so H1–H6 tags compute to#60636Bin Quick View and Full Report, instead of#181E15. These are four JSX edit sites across three component files. - Keep white-background links at their existing blue, and retain underline, hover and keyboard focus behaviour. Keep these component changes targeted; moving all global rules into a CSS layer would broaden the change.
Files: src/components/shared/layout/TipBar.tsx, src/components/report/panels/audit/AuditGroup.tsx and src/components/shared/info/HeadingStructure.tsx.
Screenshots
Comparisons from the October 8 review of the October 7 package. The supplied 4.3.0 chrome-2 package still has both overrides, checked October 12. Revised mockups show the intended colors; they do not show a shipped fix. Click any screenshot to open the original full size.
Installed screenshots · October 12
Engineering checks
Package evidence: computed colors and contrast calculations confirm the issue in both supplied packages. #2154CC raises normal-text contrast from 3.87:1 to 5.51:1 on lavender #F2E7FF, and from 4.07:1 to 5.79:1 on blue #EBF1FF.
Verify: both Quick View tip CTA variants and the Audit Tips links compute to #2154CC in the rebuilt package. Heading level tags compute to #60636B in Quick View and Full Report. Check hover and keyboard focus, then confirm white-background links retain #2969FF.
Implementation evidence: the shared Link component forwards its class to the anchor. The latest supplied chrome-2 package still has the global link and heading overrides; it requires these targeted fixes and rebuilt-package checks.
Tooltip icons overlap the Links toolbar and Parameters menu Implemented · 4.3.0 chrome-3
Verified October 13, 2026: Metric cards have the isolation root; tooltip bubbles still render through their portal and existing card actions are preserved. Supplied-package review and Beatus’s live review passed for this ticket. Original requirements and references below are retained as history; release QA is tracked separately.
Issue: Links overview tooltip icons can appear over Add/hide parameters and the toolbar when it sticks. BoxValue raises every tooltip anchor with relative z-10, including the noninteractive Links tiles. The tile has no stacking context, so its icons compete with the toolbar instead of staying inside the tile.
Fix:
- Add
isolateto theBoxValueroot:group relative isolate flex flex-col. Rebuild so the stylesheet includes this utility. The icon and extra content keep their existing stacking order inside each tile. - Keep the shared tooltip bubble portaled outside the tile. Preserve hover and keyboard behavior, and preserve the full-tile action only on tiles that already have an enabled link or button. Links overview tiles remain noninteractive.
Files: src/components/shared/box/BoxValue.tsx.
Screenshots
Historical comparisons from the October 8 design review. The supplied 4.3.0 chrome-2 package still has the same stacking mechanism, checked October 12. The proposed capture demonstrates the fix; it does not show a shipped implementation. Click a screenshot to open the original full size.
Engineering checks
Package evidence: the latest supplied 4.3.0 chrome-2 package has the unisolated tile root and raised tooltip anchors. Controlled rendering confirms that isolation contains the icon stacking. The shared tooltip bubble is portaled outside the tile.
- In Internal and External Links, open Add/hide parameters with the toolbar in its normal and stuck positions. No overview icon paints over the menu or toolbar; each toolbar control still receives clicks.
- Verify tile tooltip hover, then check shared interactive tiles with mouse and keyboard. Existing actions, focus outlines and tooltip behavior remain usable; the fix does not turn Links tiles into actions.
- Confirm the rebuilt stylesheet includes
isolation: isolateand the root computes toisolation: isolate. Check Quick View and Full Report whereverBoxValueis shared.
Info icons sit low beside metric-card labels Implemented · 4.3.0 chrome-3
Verified October 13, 2026: Metric-card info SVGs lift by 2px in Quick View and Full Report, preserving label sizes, wrapping, 14 × 14px anchors and the 4px gap. This closes the original metric-card scope. Supplied-package review and Beatus’s live review passed for this ticket. Original requirements and references below are retained as history; release QA is tracked separately.
Issue: Info icons look slightly lower than labels such as Unique Visitors, SE Traffic and Total words in Quick View and Full Report. The shared BoxValue label uses an inline tooltip with align-middle; section headings already center their label and icon with flex layout.
Fix:
- In
BoxValue.tsx, add[&>svg]:-translate-y-[2px]to the tooltip's existinganchorClass, alongsiderelative z-10and the caller's classes. Lift only the info SVG by2px; leave the tooltip anchor and label in their current positions. - Keep the existing inline
whitespace-nowraplast-word wrapper and earlier words outside it. Labels still wrap naturally, while their last word and info icon stay together on the final line, including Semrush Rank. - Keep Inter labels at
13pxin Full Report and12pxin Quick View, with the existing weight and line height. Keep the tooltip anchor and SVG at14 × 14pxand the existing4pxleft gap. Do not resize the icon or change section-heading alignment. - Preserve the tooltip's
relative z-10anchor, portal, hover and existing focus behavior, plus card actions and focus outlines. Apply this alongside Tooltip stacking; preserve that ticket'sisolateroot. Keep the alignment change local toBoxValuerather than changing everyTooltipinstance.
Files: src/components/shared/box/BoxValue.tsx. Reference: src/components/shared/Tooltip.tsx and src/components/shared/SectionHeading.tsx.
Native alignment previews
Complete Quick View and Full Report screens rendered by the actual 4.3.0 chrome-2 package, using frozen local reference data. Switch between Current and the recommended 2px SVG lift on the same screens. The package supplies the headers, tabs, native grids, fonts, icons, spacing and wrapping; only the card info-icon alignment changes.
Open Quick View and Full Report previews. Quick View renders at 640 × 600 and Full Report at 1280 × 900. Fit scales the whole screen uniformly; Actual size preserves 1:1 rendering with scrolling. The Full Report selector includes Domain Metrics, Traffic Analytics and Keyword Density.
The native-screen comparison verifies a 2px upward SVG movement, unchanged 14 × 14px anchor hitboxes, and identical label, card and section-heading geometry. The lift improves the optical alignment; it does not change section-heading icons. These previews do not access live extension settings, website probes or Semrush account data. Rebuilt-extension checks remain required.
Screenshots
User-supplied October 12 captures of the observed appearance, retained unchanged. They are references for the issue, not examples of an implemented fix; the screenshots do not display the installed version. Click any image to open the original full size.
Engineering checks
Package evidence: the supplied 4.3.0 chrome-2 package contains the same BoxValue inline last-word wrapper and Tooltip anchor classes. Its stylesheet declares text-13 as 13px, text-12 as 12px and --spacing: 4px, making size-3.5 14px. The SVG's intrinsic 16px dimensions are overridden by size-full. Reviewed source: origin/4.3.0 at ce65ab66263f51431a453e8fa126dbedd9e446ff.
- Rebuild and inspect Quick View's Semrush cards, Full Report's Domain Metrics, Backlinks Overview and Traffic Analytics, and Keyword Overview's Total words. Icons should visually align with the adjacent label text, with no downward drift.
- Check ordinary desktop width, narrow cards and browser zoom. Use both short labels and labels that wrap to two lines. The icon remains with the final word; the text keeps its normal wrapping and does not overlap the value, clip or force card overflow.
- Verify computed label font sizes remain 12px / 13px, tooltip and SVG boxes remain 14 × 14px, and the left margin remains 4px. Confirm the generated stylesheet includes
[&>svg]:-translate-y-[2px]; the SVG moves up exactly 2 CSS pixels while the anchor and inline last-word wrapper retain their current geometry. - Hover the info icons and activate existing card links/buttons with mouse and keyboard. Tooltips, destinations and focus outlines still work. Section headings retain their current alignment; the separate isolation fix still keeps icons behind the Links toolbar and Parameters menu.
Local visual evidence: same-document comparisons of native Quick View, Domain Metrics (including wrapped labels), Backlinks Overview, Traffic Analytics and Keyword Overview confirm the SVG-only lift improves alignment without moving labels, values, cards or headings. The flex alternative reduced Quick View's line-box height by 0.125px and was dropped.
Verification boundary: these are package-rendered previews with frozen fixtures. The proposed SVG-only change still needs visual and interaction checks in the rebuilt extension.
Technical Snapshot order differs between Quick View and Full Report Implemented · 4.3.0 chrome-3
Verified October 13, 2026: Both surfaces use Canonical → Robots.txt → Schema.org Markup → URL, retaining the compact Quick View treatment. Supplied-package review and Beatus’s live review passed for this ticket. Original requirements and references below are retained as history; release QA is tracked separately.
Issue: Quick View uses the revised Technical Snapshot order, but Full Report still uses its earlier order. Both surfaces should follow the approved design: Canonical → Robots.txt → Schema.org Markup → URL.
Fix:
- Use the existing
POPUP_KEYSorder on both surfaces:canonical,robotsTxt,schemaOrg,url. Remove the report-onlySNAPSHOT_KEYSlist and conditional list choice so there is one shared order. - Preserve popup compact rows, popup-only Schema result shortening and
LINK_ONLY_KEYSfor Canonical and Robots.txt. Keep the existing positional divider rules and responsive report grid.
Files: src/components/shared/info/TechnicalSnapshot.tsx.
Screenshots
Historical comparison from the October 8 design review. The supplied 4.3.0 chrome-2 package still uses two lists, checked October 12. The revised mockup shows the intended order, not a shipped fix. Click a screenshot to open the original full size.
Engineering checks
Package evidence: the latest supplied 4.3.0 chrome-2 package chooses between POPUP_KEYS and SNAPSHOT_KEYS. Using one order matches the accepted design correction.
- Quick View and Full Report read Canonical, Robots.txt, Schema.org Markup, URL. At the report’s two-column width, Canonical and Robots.txt occupy the first row, with Schema.org Markup and URL below.
- Check compact Quick View, the two-column report and a narrow single-column report. Dividers appear once at each shared edge; values, links and shortened popup Schema text keep their existing behavior.
4.3.0 What’s New copy Implemented · 4.3.0 chrome-3
Verified October 13, 2026: Both approved lines and their [+] / [*] prefixes are present. The release panel retains View all updates and Got it. Supplied-package review and Beatus’s live review passed for this ticket. Original requirements and references below are retained as history; release QA is tracked separately.
Issue: the current popup lists all five right-click destinations. Its design-refresh line needs a clearer user benefit.
Fix: replace the two marked lines in the 4.3.0 CHANGELOG block with this approved copy:
[+] Right-click a page to open reports and settings.
[*] Spot SEO issues more easily in the refreshed Quick View and Full Report.
Files: CHANGELOG.
Engineering checks
Verify: the rebuilt 4.3.0 package contains both lines exactly, including their [+] and [*] prefixes. In Quick View Settings, both lines, View all updates and Got it remain fully visible; text wraps within the What’s New column without clipping.
URL Backlinks uses cleaned page URLs Implemented · 4.2.3 candidate
Implemented in the 4.2.3 candidate. Package checks confirm that API lookups, cache keys and Semrush click-through links use the same cleaned page URL. Identifying parameters, original CSV URLs, attribution and security exclusions are preserved. Installed-browser smoke checks remain.
Original issue and implementation reference
Original issue: Google adds srsltid to some result URLs. The SERP’s URL Backlinks metric and its Semrush link keep that parameter, so they look up the tracking variant instead of the page. Analyze already removes it.
Observed Sep 30 · chrome-5: the SERP export shows 0 URL backlinks for GoodRx, Segafredo and Ember Coffee. The AI-source exports use the same pages without srsltid and show 26, 17 and 1. The supplied GoodRx and Segafredo backlink links also include srsltid in Semrush’s q value. These are snapshot values, not targets to hardcode.
Original guidance:
- Use the same cleaned page URL for the URL Backlinks lookup, its cache key and its Semrush click-through link. Share the existing Analyze cleanup rather than adding a second set of rules. Cover the SERP strip, AI source cards and Analyze sources panel, plus other consumers of the shared backlink helpers.
- Remove known tracking parameters and fragments only. Keep the protocol, host, trailing slash and parameters that identify the page, such as YouTube’s
v, product IDs and pagination. Keep domain and subdomain backlink scope, tracking attribution and result numbering unchanged. - Keep the original result URLs in CSV and export the corrected backlink count. Use the cleaned URL only for Semrush analysis. Navigation and link-status/security checks must keep their original URLs, query strings and action exclusions.
Browser checks and files
Verify: with and without srsltid, the same page uses one backlink target and shows the same count in the strip, AI sources and CSV. Clicking URL Backlinks opens that cleaned page in Semrush’s URL mode. Identifying parameters still select distinct pages.
- Reuse Analyze’s current cleanup:
srsltid,utm_*,gclid,dclid,fbclid,msclkid,mc_cid,mc_eid,_gaand_gl, matched case-insensitively, plus fragments. Preserve unknown parameters. Removetonly on YouTube, as Analyze does today. - Compare fresh lookups for the linked GoodRx and Segafredo pages with and without
srsltid. Confirm a cached tracking-variant zero cannot replace the cleaned page’s result. Check the API target, metric, click-throughqand CSV count agree; current Semrush numbers may have changed. - Check a trailing-slash page, HTTP and HTTPS, a
wwwhost, YouTubev, a product ID and pagination. Distinct identifying queries must retain separate backlink targets and cache keys. Domain/subdomain links and the existingserp_backlink_analytics/serp_metric_backlinksattribution remain intact. - Retest a token-bearing action URL after adding the shared cleaner. The original URL must still be Skipped by security checks and never requested. Do not change the security URL normalizer or query-preserving status cache.
Files: src/utils/parameters/semrushBacklinks.ts, src/utils/parameters/helpers.ts and the backlink cache/handler, src/utils/semrush/metricLinks.ts, the Analyze cleanup in src/utils/semrush/overviewLinks.ts, and the SERP/AI metric and CSV consumers.
Visible headings with a leftover clip are treated as hidden Implemented · 4.2.2
Verified Sep 29: the 4.2.2 build honors clip only on absolute or fixed elements. The hidden-heading regression suite passes on the built code, including the static-clip case that failed in 4.2.0. Still to check on the final build: the live Google retest below.
Issue: hasCollapsedClip in src/utils/serp/google/headings.ts treats any collapsed clip: rect(...) as hidden. In CSS, clip only applies to elements positioned absolute or fixed. On a static or relative element it does nothing and the heading stays visible, but Chrome still reports the value. Two effects:
- AI Overview detection skips the module, so the Analyze sources panel and the card metrics disappear. Reproduced in 4.2.1 on live Google with manually injected CSS (screenshots below).
- An organic feature module’s visible title is skipped, so its cards can be counted as results and the numbering shifts. Shown in a real-browser fixture during the September 17 review.
Present since 4.2.0, when the September 17 review first flagged it. Not seen occurring naturally on Google.


4.2.1 · September 28 · Clip injected with DevTools · Click a screenshot to open it full size.
Fix: only honor the legacy clip when the element carrying it is positioned absolute or fixed. hasCollapsedClip runs once per ancestor with that element’s own style, so the condition goes inside it:
if (clip?.[1] && (style.position === 'absolute' || style.position === 'fixed')) {
Leave the clip-path check and the other hiding checks (display, visibility, opacity, 1×1 size) unchanged.
Verify on a results page with an AI Overview, in DevTools. Set up once:
const h = [...document.querySelectorAll('h2, [role="heading"][aria-level="2"]')].find(el => /AI Overview/i.test(el.textContent) && el.getBoundingClientRect().height > 0);
const p = h.parentElement, saved = [h.style.cssText, p.style.cssText];
const reset = () => { h.style.cssText = saved[0]; p.style.cssText = saved[1]; };
h.style.position = 'static'; h.style.clip = 'rect(0px, 0px, 0px, 0px)';The heading stays visible, and so does the Analyze sources pill. Today the pill disappears. Thenreset().p.style.position = 'absolute'; p.style.clip = 'rect(0px, 0px, 0px, 0px)';The heading really hides, and the pill disappears too.p.style.position = 'static';Same clip, now ignored: the heading and the pill come back. Today the pill stays gone. Thenreset().
Regression: keep the hidden-heading checks green. The first result of each group keeps its strip and number, and module exclusions (People also ask, AI Overview, carousels) don’t change. An independent review applied this condition to the shipped code in memory and passed 33 of 33 real-Chrome checks and 18 of 18 applicable package regressions. The rebuilt extension still needs the checks above.
Files: src/utils/serp/google/headings.ts.
Analyze opens the whole domain, not the result’s page Implemented · 4.2.2
Verified Sep 29: Analyze on the SERP strip, in the Analyze sources panel and on the source cards opens the result’s page in Exact URL mode, tracked as serp_page_overview or serp_ai_page_overview. The cleanup cases pass on the built code, and live clicks opened the page on the search country’s database (US and France). Rank, Traffic and Costs stay on the domain.
Issue: on the SERP strip, in the Analyze sources panel and on the source cards, Analyze opens Domain Overview for the root domain, the same place the Rank, Traffic and Costs links go. All four links share one campaign (serp_domain_overview or serp_ai_domain_overview). Their utm_content already differs (…_cta_analyze vs …_metric_semrush_rank), but our Stork reports group by campaign, so Analyze clicks can’t be told apart there. For a single result or cited source, the page itself is the more useful report: Domain Overview in Exact URL mode shows that page’s organic traffic, keywords and backlinks. This replaces the domain-level Analyze accepted for 4.2.1.
Fix:
- Point Analyze on the SERP strip, in the Analyze sources panel and on the source cards at the result’s own URL with
searchType=url, for examplehttps://www.semrush.com/analytics/overview/?q=https%3A%2F%2Fwww.visitflorida.com%2Fplaces-to-go%2Fsoutheast%2Ffort-lauderdale%2F&protocol=https&searchType=url&db=us. Keep the country fromdatabaseCountry.ts. - Keep Rank, Traffic and Costs on the domain. They’re domain metrics, so their links keep domain scope.
- Give Analyze its own tracking destination, for example
page_overviewinSemrushDestination(src/utils/semrush/utm.ts). The campaigns becomeserp_page_overviewandserp_ai_page_overview. - Build the link from the result’s or source’s own URL, cleaned. Exact URL is a literal match, so remove the
#fragment (Google adds#:~:text=to cited links), tracking parameters such asutm_*, andt=on YouTube only. Keep everything else: the protocol,www, the trailing slash and query parameters that identify the page (YouTube’sv=, product IDs, pagination). Don’t reuse the current target normalizer, which strips trailing slashes, or the domain builder, which hard-codesprotocol=https.
Files: SerpAnalyzeCta.tsx, AiSources.tsx, src/utils/semrush/overviewLinks.ts (add a page-level URL builder) and src/utils/semrush/utm.ts.
Coordinate with “AI Overview source cards wrap unevenly”. Both change AiSources.tsx and the Analyze component (SerpAnalyzeCta.tsx), but each can ship on its own.
Measure: compare the last full week before 4.2.2 ships with each full week after it, counting only weeks when that version is on about 90% of daily users (check “Daily users by item version”). From the same Stork report, report visitors, registrations and registrations per visitor for serp_domain_overview, serp_page_overview, serp_ai_domain_overview and serp_ai_page_overview, with the SERP strip and AI placements shown separately. For reference, September 21 to 27 on 4.2.0 had 136 registrations from 3,433 visitors (4.0%, Content Performing), counting Analyze and the Rank, Traffic and Costs links together. Treat the results as directional, not proof.
AI Overview source cards wrap unevenly Implemented · 4.2.2
Verified Sep 29: narrow columns show two rows, connected and not connected, and wide columns show one, with Analyze always visible. Still to check on the final build: very narrow cards and cards with fewer metrics.
Issue: Google’s source cards change width from one results page to the next, and the compact metrics wrap by the length of their values. Cards in the same column end up with one, two or three rows: “Traffic 98K” fits on a line where “Traffic 1.47M” wraps. The cause is in the compact branch of AiSources.tsx: the metric row is a wrapping flex row with right padding (pr-18, or pr-20 when tight) that holds space for Analyze. That padding applies to every line, not only the last, so AS and Traffic can’t share a line in a narrow column.



4.2.1 · September 28 · Click a screenshot to open it full size.
Fix:
- Hold Analyze’s space on the last row only. Replace the wrapping row with a two-column grid: two metrics on row 1, the third metric on row 2, and Analyze in the free space to its right, where
SerpAnalyzeCtaalready sits.- Connected, default parameters: AS and Traffic, then L and Analyze.
- Not connected, default parameters: Traffic and L, then LD and Analyze.
- Wide columns stay on one row. The card already measures its width with a resize observer (it sets
ai-compact-tight); use the same check to choose one row when the metrics and Analyze fit, otherwise the two-row grid. Two rows at most, unless a column is too narrow even for the grid: then wrap, and give Analyze its own row if it needs one. - Keep the person’s metric selection and the current
AI_COMPACT_PRIORITYorder: up to three metrics, AS plus two when connected, three when not. Parameters that are turned off stay off, and cards with fewer metrics still lay out cleanly. This is a layout change only. - Keep Analyze on the cards.
- Limit the change to the compact card. The SERP strip shares
SerpAnalyzeCta, and its layout stays as it is.
Verify: connected and disconnected cards, long values, fewer metrics, and resizing across one-row and two-row widths. Every metric and Analyze stay visible, with nothing overlapping or clipped.
Files: src/components/serp/AiSources.tsx (compact branch) and src/assets/styles/serp.css; SerpAnalyzeCta.tsx only if its clearance check needs to know about the grid.
Coordinate with “Analyze opens the whole domain, not the result’s page”. Both change AiSources.tsx and the Analyze component (SerpAnalyzeCta.tsx), but each can ship on its own.
Settings don’t save until you click Save Implemented · 4.2.2
Verified Sep 29: the Save button is gone. Checkboxes save immediately, and text fields save after a pause, on blur and when leaving. Saves run in order, a confirmed Reset wins over pending saves, and a failed save keeps the edit with a working Try again. Controlled tests on the built code pass. Still to check in the running extension: typing a new line, closing Settings mid-edit and a failed save.
Issue: on the Parameters, SEObar and SERP Overlay tabs in Settings, each change only updates a draft. Nothing is stored until the person clicks Save. The SERP sidebar’s Parameters dropdown saves on every click (patchSerpSettings), and the General tab already saves its toggles right away. There is no unsaved-changes warning, so closing Settings or going back to the Full Report drops the changes without telling anyone.
Fix:
- Save checkbox and radio changes as soon as they’re made on those three tabs, the same way the SERP sidebar dropdown does.
- Text fields (stop words, whitelist, SEObar matches and excludes) save after a short pause, on blur, and before leaving Settings. Don’t rewrite a field with its trimmed value while the person is typing, or the new line they just started disappears.
- Save one change at a time, in order. Each save writes the whole settings object, so two overlapping saves can lose an edit.
- Remove the Save button once every field saves on its own. Keep “Reset to default” and its confirm step. A confirmed Reset clears queued edits and prevents an earlier save from overwriting the reset values.
- Show a message only when saving fails, using the existing “Couldn’t save … Try again.” notice, and keep the edit so Try again can retry it. No success message.
- The sidebar dropdown’s save (
patchSerpSettings) reports success even when the write fails. Fix it along with the rest.
Files: ParametersPanel.tsx, SeobarPanel.tsx and SerpPanel.tsx in src/components/settings/panels/ (the draft state and handleSave), and SettingsStickyActions.
Some Semrush links open the wrong country database Implemented · 4.2.2
Verified Sep 29: on google.com, .co, .me and .ly results fall back to US unless Locale or gl picks the country, and the SEObar, Links table and Compare pass the page URL. Resolver cases pass on the built code, and a France Locale opened the FR database. Still to check on the final build: live clicks from those three surfaces.
Issue: two gaps remain after the 4.2.1 country fix.
- Generic-looking endings: on google.com with no Locale and no
glparameter, results ending in.co,.meor.lyopen the Colombia, Montenegro or Libya database. These endings are mostly used like.com(angel.co, about.me, bit.ly). - Still on US: three callers don’t pass a country, so they still open
db=us:- SEObar Rank, Traffic and Costs links:
SeobarParameters.tsxrendersParameterByKeywithoutsemrushCountry. - Full Report Links table:
LinksTable.tsxcallsgetSemrushMetricHref(itemKey, target). - Compare:
buildRows.tscallsgetSemrushMetricHref(key, column.target).
- SEObar Rank, Traffic and Costs links:
Fix:
- Generic-looking endings: in
countryFromTargetinsrc/utils/semrush/databaseCountry.ts, ignoreco,meandly, so they fall through tous. Keep them in the supported-country list, so a Locale orglchoice of Colombia, Montenegro or Libya still works. - Still on US: resolve the country from the URL string, the country ending only, the same way Quick View does. In SEObar, pass
resolveSemrushDatabaseCountry(pageUrl)assemrushCountry. In LinksTable useresolveSemrushDatabaseCountry(target.pageUrl), and in CompareresolveSemrushDatabaseCountry(column.target.pageUrl), then pass it togetSemrushMetricHref. Those targets are objects: passing the object itself silently falls back to US.
Percentages show up to two decimals Implemented · 4.2.2
Verified Sep 29: the shared formatter shows exactly one decimal (61.2%, 100.0% on the SERP strip and AI panel), and CSV exports keep two.
Issue: bounce rate and Traffic Channel Distribution use formatPercentage in src/utils/format.ts, which allows up to two decimals and drops trailing zeros. The same SERP strip shows “69.6%” next to “88.11%” and “56.23%”, and the channel chart shows “41.28%”. The second decimal is false precision on a Semrush estimate.


4.2.1 · September 28 · Click a screenshot to open it full size.
Fix: format with exactly one decimal, toLocaleString('en-US', { minimumFractionDigits: 1, maximumFractionDigits: 1 }): 88.11% becomes 88.1%, 41.28% becomes 41.3%, and 41% becomes 41.0%. formatPercentage has two callers, trafficAnalytics.ts (bounce rate) and trafficSources.ts (Traffic Channel Distribution), so the one change covers:
- SERP overlay connected row: Bounce rate.
- AI Overview sources panel connected row: Bounce rate.
- Popup, Semrush tab: Bounce Rate tile and Traffic Channel Distribution.
- Full Report, Semrush tab: Bounce Rate tile and Traffic Channel Distribution.
Leave as is: CSV exports keep two decimals, since they’re for analysis. Keyword density and text/HTML ratio already use one decimal. Image alt text, image formats and the backlink country breakdown use whole numbers.
Semrush Rank and Traffic Cost links open a subfolder report Implemented · 4.2.2
Verified Sep 29: Rank, SE Traffic and Traffic Cost all use the domain link builder, each with its own tracking. Still to check on the final build: live clicks in the Full Report and Quick View.
Issue: in the shared Semrush overview, the Semrush Rank and Traffic Cost links open Domain Overview with searchType=subfolder for the page URL, while their tooltips describe the domain and the SE Traffic link next to them opens the domain. The Full Report shows all three. Quick View hides Rank but shows Traffic Cost.
Fix: build both links with domainAnalyticsOverviewUrl(target, country), like SE Traffic, in src/components/shared/semrush/SemrushOverview.tsx. Keep each link’s own tracking. Verify Rank and Traffic Cost in the Full Report and Traffic Cost in Quick View, on a deep page URL with a non-US country ending.
Lookalike domains pass the Google check Implemented · 4.2.1 chrome-3
Verified Sep 24: The host check now matches Google’s real domains only. A lookalike domain gets no sidebar and no strips.
Issue: The Google host rule in src/utils/serp/google/match.ts accepts any two words after “google.”, so www.google.example.com gets the SERP sidebar and overlays. Reproduced in the shipped 4.2.0 build and unchanged on the 4.2.1 ai branch, where the AI Overview detection uses the same check. The same check gates the background lookup for Google’s /goto redirect links, so on a lookalike page SEOquake also sends requests to that site’s own server, without cookies. The SERP script scope fix neither causes nor fixes it. Risk is low: a lookalike site gets metric strips and those requests, and SEObar already analyzes every site. It’s a one-line change, so include it in 4.2.1 while this code is open.
Fix: Require a real Google ending:
// Current: /^(?:www\.)?google\.[a-z]{2,}(?:\.[a-z]{2,})?$/i
const GOOGLE_HOST_PATTERN =
/^(?:www\.)?google\.(?:com?\.[a-z]{2}|[a-z]{2,3})$/i;
Tested against Google’s official list of 187 search domains (google.com/supported_domains), with and without www.: the new rule accepts all of them. It rejects google.example.com, google.evil.co, google.company.io, google.co.evil and google.com.evil, which the current rule accepts. urls.ts uses the same rule for redirect detection, so rerun the URL tests after the change.
Full Report Audit info icon alignment Implemented · 4.3.0 chrome-4
Verified October 13, 2026: All 26 Full Report Audit check-label SVGs have the scoped 2px lift in chrome-4. Computed styles were checked in the supplied extension with controlled page data.
Implemented fix · reference
AuditItemHeader.tsxapplies[&>svg]:-translate-y-[2px]to the check-label tooltip’sanchorClass. Only the SVG moves; preserve the label’srelative top-px, anchor and existing geometry.- Keep all 8 Page Analysis, 2 Mobile Compliance and 16 Technical Compliance rows, label sizes/wrapping,
14 × 14pxanchors/SVGs,4pxgap, status icons and tooltip behavior. No globalTooltiplift.
Files: src/components/shared/info/AuditItemHeader.tsx; caller src/components/report/panels/audit/AuditGroup.tsx. Release checks for zoom, wrapping and tooltip interactions remain separate from this implementation closeout.
Revisions · September 17, 2026
Revisions · September 16, 2026
Originally retested with chrome-3; resolution statuses updated September 17 for chrome-4. Original issue descriptions remain for context.
1. Google /goto links — missing overlays Passed
Issue: In the tested incognito results, Google uses /goto links. The current parser rejects them, leaving some queries with one overlay and others with none. Legacy instead treats these links as Google destinations and repeats Google’s metrics across unrelated results.
Fix: Update the Google redirect resolver, which currently recognizes only /url and /url/…, to handle the observed /goto format. Inspect an actual link and its destination metadata to determine the extraction method, then pass the resolved HTTP(S) URL through the existing validation and metric pipeline, preserving its path and query. Never pass the Google redirect itself as the target; skip its overlay if unresolved.
2. Skipped Google results — incorrect numbering Resolved in chrome-4
History: Failed in chrome-3; resolved in chrome-4. See the September 17 diagnosis and verification.
Issue: Legitimate www.google.com results are filtered out. Positions count only accepted results, so Reddit appears as #2 instead of #3; a second skipped Google result shifts later positions again.
Fix: Replace the URL validator’s blanket rejection of www.google.com destinations with filtering that distinguishes genuine organic pages from Google navigation and redirects. Replace numbering based on the accepted-results array (position: r + a.length + 1 in the supplied bundle) with the eligible organic result’s position, calculated before overlay-specific skips. Exclude AI Overview, People also ask and video carousels from this count.
In the screenshot: Google Developers #1, Google #2, Reddit #3, Neil Patel #4, Medium #5, Google #6, GeeksforGeeks #7, Semrush #8.
3. Dark Google pages — unreadable top row Passed
Issue: The top row uses bg-gray-light/50 with dark text. Google’s dark background shows through the 50% transparent gray, reducing contrast. The opaque bottom strip stays readable.
Fix: Replace bg-gray-light/50 with an opaque background matching the approved light-page appearance, approximately #ECECEC. Apply it to both connected metrics and the disconnected teaser so the same design stays readable on light and dark Google pages.
4. Strips and tooltips overlap Google’s interface Passed
Issue: Near-maximum layers put SEOquake above Google’s sticky header and autocomplete in both themes: overlays 2147483645, sidebar 2147483646, tooltips 2147483647. An opaque background alone will not fix this.
Fix: Keep each result overlay in the page’s normal layer and contain its tooltip within it. Start by changing the result overlay’s shadow-host CSS:
:host {
position: relative;
z-index: 0; /* replace 2147483645 */
}
This creates a local stacking context. The existing tooltip portal stays inside the overlay’s shadow root, so its high internal layer cannot lift it above the host’s layer.
- Lower the sidebar’s layer below Google’s menus. If needed, raise only the active result overlay slightly to let its tooltip overlap adjacent strips, keeping it below Google’s header and suggestions.
- Dismiss any open SEOquake tooltip when focus enters Google’s search field. Confirm the final layers keep both strips and tooltips below the header and autocomplete.
- Change SEOquake’s elements only; leave Google’s styles alone.
More technical fixes
Implemented. See each item’s verification and remaining checks. The original diagnosis and guidance are kept as history.
Destination URL Implemented · 4.2.0
Background: Diagnosed September 11 against the supplied 4.1.2 package and the SERP branch at 51b50b5. Implemented in 4.2.0 and passed the September 17 smoke tests. The original guidance below is kept as history.
Required outcome: identify each result by its actual destination, never by an address reconstructed from Google’s displayed breadcrumb.
Confirmed problem: resolveResultUrl() prefers extractCiteUrl() over the title link. Tests with the supplied code collapse distinct /a and /b pages into one domain, or invent /Products/Widget instead of the real /products/detail?id=42 destination.
Implementation guidance
- Use the title anchor already selected by
findHeadingLink(). Parse its non-emptyhrefagainst the document base URL. Remove breadcrumb reconstruction from URL identity; do not fall back to it when a link is missing or invalid. - Unwrap only recognized Google-hosted redirects. For supported
/urllinks, extract a validqorurldestination and validate it again. Do not unwrap a third-party site merely because its path is/url. Keep existing ad and result-eligibility exclusions. - Accept only a resolved, eligible HTTP(S) destination. If a redirect form cannot be resolved safely, skip that URL-dependent overlay/export row; do not send Google’s redirect URL to the metric service. Add a captured fixture before supporting another redirect form such as
/goto. - Use the resolved URL consistently for result identity, CSV URLs and inputs to page-level metrics/report links. Keep domain-level metrics domain-scoped. Preserve the destination’s path and query; do not merge different pages by domain or displayed breadcrumb.
Follow the URL through the shared helpers. normalizeSemrushTarget() currently calls normalizeUrl(), which removes every query parameter. A resolver-only fix therefore does not preserve ?id=42 versus ?id=43 in page-level requests and report targets. Preserve query identity in the page-target path and test its callers, caches and generated requests. Do not globally change the shared normalizer without regression checks. This is an existing shared dependency, not established as a new SERP regression.
QA checklist
Run after implementation. These are checks to cover, not necessarily separate automated tests.
| Test | Required result |
|---|---|
| Different pages, same domain | Links to /a and /b remain distinct even when their displayed breadcrumbs show only the domain. |
| Misleading or absent breadcrumb | The real /products/detail?id=42 link wins over “Products › Widget”. For an otherwise eligible result, an absent cite does not prevent resolving its valid title-link destination. |
| Google redirect and ordinary /url page | Supported Google /url?q=… and /url?url=… links resolve correctly. An external site’s /url?q=… address remains that site’s URL. |
| Invalid or unresolved destination | Missing href, non-HTTP(S), excluded ads and unresolved Google redirects produce no guessed URL or metric request. |
| Meaningful query parameters | ?id=42 and ?id=43 remain distinct in results and CSV, and in page-level request/cache/report targets; domain metrics retain their existing scope. |
Source: URL resolution · detection and deduplication · metric target normalization · shared URL normalizer. Legacy 3.13.5 read the selected result link’s href directly; it did not reconstruct the breadcrumb.
Verification boundary: isolated original-code tests reproduce the URL-resolution defect. The acceptance cases above still require the implemented extension, including mixed Google results and coexistence with other extensions. This handoff is not release approval.
Archive 4
Earlier release checks, browser examples and build comparisons.
4.3.1 release details
Final package: 4.3.1-chrome-3-seobar-3. All 19 release-review cards are complete.
Milestones: Beatus confirmed submission October 29 at 11:42 a.m. EDT and rollout set to 100% November 2 at 11:22 a.m. EST. Distribution is not measured adoption.
Verification: 12 tooltip scenario groups passed. Beatus’s live review confirmed report tooltips, SEObar/SERP appearance, typing and nonediting S shortcuts, reports, metrics and the retained Semrush connection. The existing Store installation passed his November 2 upgrade smoke test.
4.2.0 release verification · September 17
Shipped in 4.2.0
Release package: Robert’s chrome-4. All 35 files match the reviewed build.
| Area | Status |
|---|---|
| SERP Overlay, missing listings and initial numbering | Implemented · Tested |
| Semrush connection and connected metrics | Implemented · Tested |
| Quick Parameters autosave, country/language and Reset | Implemented · Tested |
| Dark backgrounds, header and autocomplete layering | Passed smoke tests |
| SERP CSV exports and page-two offset | Verified exports |
| Dynamic numbering after insertion/removal | Bundled-handler test passed |
Evidence: Chrome smoke tests confirmed on this exact package. Nine CSV exports contained 66 rows, with consistent numbering and columns. Fort Lauderdale page two runs from #11 to #20. Locale exports include German, Chinese-language and Russian destinations; the files do not record the selected locale.
Package checks: 12 JavaScript files parse; referenced resources exist. Regression suite: 18 of 19 checks passed. This records the September 17 package result. It is not the current 4.3.1 open-work count.
Legacy version
3.13.5Explore the iPhone lineup. Compare models, discover their features, and find the right iPhone for you.
Original styling; result number outside the bar.
Previous build
Package 4.1.2Explore the iPhone lineup. Compare models, discover their features, and find the right iPhone for you.
Current styling reference.














































