Skip to content

[recovery] Guard localStorage access in TranslationBanner against SecurityError - #19192

Draft
ethorg-agent-code[bot] wants to merge 1 commit into
devfrom
recovery/fix/translation-banner-localstorage-securityerror
Draft

[recovery] Guard localStorage access in TranslationBanner against SecurityError#19192
ethorg-agent-code[bot] wants to merge 1 commit into
devfrom
recovery/fix/translation-banner-localstorage-securityerror

Conversation

@ethorg-agent-code

Copy link
Copy Markdown

Production error

  • Message: SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
  • URL: https://ethereumorg-ow.sentry.io/issues/7705044554/ (fingerprint sentry-ETHORG-1AF)
  • Occurrences: 1 (cumulative since first seen 2026-09-01T16:59:10Z)
  • Culprit: /:locale

Root cause

TranslationBanner (src/components/TranslationBanner/index.tsx) is rendered on every page via BaseLayout, matching the reported /:locale culprit. Its useEffect read localStorage.getItem(lsKey) directly, and handleDontShow wrote via localStorage.setItem(lsKey, "true") directly, with no error handling.

Some browsers/environments deny access to the localStorage property itself (not just individual keys) -- e.g. strict privacy settings, certain private-browsing modes, or storage-partitioning restrictions -- which throws a SecurityError synchronously rather than returning null. Since this call happened directly in a useEffect/event handler with no try/catch, the exception propagated uncaught.

The project's own useLocalStorage hook (src/hooks/useLocalStorage.ts) already wraps all localStorage access in try/catch for this exact reason, but TranslationBanner predates/bypasses that hook and accesses localStorage directly.

Fix

Wrap both the read (in the useEffect) and the write (in handleDontShow) in try/catch, defaulting to showing the banner if the read fails, matching the defensive pattern already used elsewhere in the codebase (src/lib/utils/matomo.ts, useLocalStorage.ts).

Verification

  • pnpm type-check -- passes
  • pnpm exec eslint src/components/TranslationBanner/index.tsx -- clean, no warnings/errors

Some browsers deny access to the localStorage property entirely (e.g.
strict privacy settings), which throws a SecurityError rather than
returning null. Wrap both the read and write in try/catch so the
banner degrades gracefully instead of crashing the effect.
@ethorg-agent-code ethorg-agent-code Bot added the recovery-agent Created by the Recovery Agent label Sep 1, 2026
@netlify

netlify Bot commented Sep 1, 2026

Copy link
Copy Markdown

Deploy Preview for ethereumorg ready!

Name Link
🔨 Latest commit c7b1ecc
🔍 Latest deploy log https://app.netlify.com/projects/ethereumorg/deploys/6a97136afbf9610008d2b57d
😎 Deploy Preview https://deploy-preview-19192.ethereum.it
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
7 paths audited
Performance: 61 (🔴 down 4 from production)
Accessibility: 96 (no change from production)
Best Practices: 100 (🟢 up 1 from production)
SEO: 98 (no change from production)
PWA: 60 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

recovery-agent Created by the Recovery Agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants