Skip to content

[Feature]: Add session persistence for per-tab browsing context using localStorage so context survives page refresh #229

Description

@divyanshim27

Summary

SuperBrowser's core value proposition is its per-tab context engine — every search query, result, and visited page is captured into an isolated tab context that the AI uses for grounded, personalized answers. However, this context is held entirely in memory on the backend (in memory on the backend, scoped per session_id → tab_id, with a 1-hour idle TTL). If a user refreshes the page, closes the tab accidentally, or the browser restarts, the entire research session is lost. This directly undermines the "smarter, grounded answers" promise for real research workflows.

Problem
The frontend useContextManager.js hook manages tab state in React component memory. A page refresh resets all tabs and their contexts to empty.
The backend context is keyed by session_id → tab_id, but the session_id is not persisted on the frontend across page loads, so even if the backend TTL hasn't expired, a refreshed page generates a new session_id and loses the old context.
The 🧠 Context: X searches, Y results badge resets to zero on refresh.
There is no visible session restoration UI to inform users that their context was saved and recovered.
Impact
Users doing multi-step research (the core use case) lose their entire session if they accidentally refresh — a common browser behaviour.
The JSON export feature is the only recovery option, but it requires the user to have manually exported before the refresh.
This limits SuperBrowser's viability as a serious research tool compared to maintaining a simple browser history.
Proposed Solution

  1. Persist session_id in localStorage (frontend):

javascript
// frontend/src/config/sessionManager.js
const SESSION_KEY = 'superbrowser_session_id';

export const getOrCreateSessionId = () => {
let sessionId = localStorage.getItem(SESSION_KEY);
if (!sessionId) {
sessionId = crypto.randomUUID();
localStorage.setItem(SESSION_KEY, sessionId);
}
return sessionId;
};

export const clearSession = () => {
localStorage.removeItem(SESSION_KEY);
};

  1. Persist tab context snapshots in localStorage:

In useContextManager.js, after each context update (new query, result, or visited page added), serialize the relevant tab's context to localStorage:

javascript
const persistTabContext = (tabId, context) => {
const key = superbrowser_context_${tabId};
localStorage.setItem(key, JSON.stringify(context));
};

const restoreTabContexts = () => {
const restored = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key.startsWith('superbrowser_context_')) {
const tabId = key.replace('superbrowser_context_', '');
restored[tabId] = JSON.parse(localStorage.getItem(key));
}
}
return restored;
};

  1. On page load in App.jsx, restore persisted tab contexts:

javascript
useEffect(() => {
const restoredContexts = restoreTabContexts();
if (Object.keys(restoredContexts).length > 0) {
setTabContexts(restoredContexts);
showToast('Research context restored from your last session');
}
}, []);

  1. Add a "Clear Session" button to the context badge UI so users can intentionally wipe their session and start fresh.

  2. Backend: extend session TTL or add a heartbeat ping from the frontend every 10 minutes to keep the server-side context alive for active sessions.

Acceptance Criteria
session_id persisted in localStorage and reused across page reloads
Per-tab context (queries, results, visited pages) serialized to localStorage after each update
Tab contexts restored from localStorage on page load with a toast notification
"Clear Session" button added to the context badge component
No sensitive data (API keys, full page content beyond the tracked 5,000 chars) persisted in localStorage

I would be happy to implement this end-to-end. Could you please assign this issue to me?

Labels: enhancement, feature-request, frontend, user-experience, help wanted, GSSoC 2026


Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    GSSoCUnder GirlScript Summer of Code

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions