How the History Sidebar Persists and Retrieves Generated Images in Open Generative AI
The history sidebar in Anil-matcha/Open-Generative-AI uses the browser's localStorage API with the storage key muapi_history to persist up to 50 recent generations, retrieving them on component mount to render vertical thumbnail navigation.
The Open Generative AI repository implements a client-side persistence layer for generated media across its studio components. When users create images, videos, or lip-sync content, the application stores generation metadata locally to survive page reloads and browser restarts.
Writing Generation Records to localStorage
When an image generation completes successfully, the ImageStudio component pushes a new record into an in-memory generationHistory array. According to the source code at src/components/ImageStudio.js:1001, the component captures the URL, an 80×80 base64 thumbnail, the prompt text, and model metadata.
The component then serializes this data and stores it in the browser's localStorage:
// src/components/ImageStudio.js (line 1001)
generationHistory.push({
url, // URL of the generated image
thumbnail, // 80×80 base64 thumbnail
prompt, // prompt that produced it
model, // model identifier
// ... other metadata
});
localStorage.setItem('muapi_history',
JSON.stringify(generationHistory.slice(0, 50)));
The slice(0, 50) operation ensures only the newest 50 entries are retained, preventing unbounded storage growth that could exceed browser quotas.
Retrieving History on Initialization
When the ImageStudio UI mounts, it reads the stored JSON string back into the application state. As implemented at src/components/ImageStudio.js:1065, the component parses the muapi_history value or defaults to an empty array if no history exists:
// src/components/ImageStudio.js (line 1065)
const saved = JSON.parse(
localStorage.getItem('muapi_history') || '[]');
generationHistory.push(...saved);
This initialization pattern allows the sidebar to display previous generations immediately upon page load, creating a seamless user experience across browser sessions.
Rendering the History Sidebar UI
The sidebar interface is constructed using vanilla JavaScript DOM manipulation with Tailwind CSS utility classes for positioning and transitions.
DOM Structure and CSS Transitions
At src/components/ImageStudio.js:931, the component creates a fixed-position container that initially renders off-screen using transform utilities:
// src/components/ImageStudio.js (line 931)
const historySidebar = document.createElement('div');
historySidebar.className =
'fixed right-0 top-0 h-full w-20 md:w-24 ... translate-x-full opacity-0';
historySidebar.id = 'history-sidebar';
When the user toggles the sidebar visibility, the component removes the translate-x-full and opacity-0 classes and adds translate-x-0 and opacity-100 to slide the panel into view, as seen at line 1004:
// src/components/ImageStudio.js (line 1004)
historySidebar.classList.remove('translate-x-full', 'opacity-0');
historySidebar.classList.add('translate-x-0', 'opacity-100');
Thumbnail Generation and Display
The sidebar content is rebuilt from the generationHistory array each time the history changes. The component clears the container and iterates through the array to create image elements (lines 1011-1025):
historyList.innerHTML = '';
generationHistory.forEach(entry => {
const thumb = document.createElement('img');
thumb.src = entry.thumbnail;
thumb.alt = entry.prompt;
// ...append to list
});
This approach ensures the UI stays synchronized with the underlying data structure while displaying 80×80 pixel thumbnails for quick visual scanning.
Implementation Across Studio Components
The persistence pattern is consistent across the codebase, though each studio maintains its own UI initialization.
VideoStudio (src/components/VideoStudio.js) implements identical read/write logic at lines 709-720 and 791-792, using the same muapi_history storage key. This allows video generations to appear in the same history stream as images.
LipSyncStudio (src/components/LipSyncStudio.js) follows the same architectural pattern with component-specific DOM IDs (e.g., lipsync-history-sidebar), executing storage operations at lines 466-478 and 533-534.
Client-Side Storage Architecture
The history mechanism relies entirely on browser-based storage with no server-side persistence. This design provides immediate offline access and eliminates network latency for history retrieval, though it limits history to the specific browser and device.
The stored JSON structure contains:
- url: Direct link to the generated asset
- thumbnail: Base64-encoded 80×80 pixel preview image
- prompt: Original text prompt used for generation
- model: Identifier for the AI model utilized
- timestamp: Generation time (implied by array ordering)
Summary
- The ImageStudio, VideoStudio, and LipSyncStudio components share a unified client-side persistence layer using the
localStoragekeymuapi_history. - Each generation creates an entry containing a base64 thumbnail, asset URL, and metadata, stored as a JSON-serialized array capped at 50 entries.
- The sidebar UI is constructed with dynamic DOM manipulation and CSS transform transitions, rendering retrieved history immediately on component mount.
- All data remains in the browser; no server-side storage is utilized for the history feature.
Frequently Asked Questions
Where is the generation history stored?
The history is stored exclusively in the browser's localStorage under the key muapi_history. As implemented in src/components/ImageStudio.js, the application uses localStorage.setItem() and localStorage.getItem() to persist and retrieve the JSON-serialized history array, meaning data survives page reloads but remains specific to the individual browser.
How many generated images does the history sidebar retain?
The application maintains a maximum of 50 entries in the history array. According to the source at src/components/ImageStudio.js:1001, the code uses generationHistory.slice(0, 50) to truncate older entries before writing to localStorage, preventing storage quota violations while keeping recent generations accessible.
Is history shared between different studio types?
Yes, VideoStudio and ImageStudio share the same muapi_history key, meaning video generations appear alongside image generations in the sidebar. The LipSyncStudio component also utilizes the same storage mechanism, though it maintains distinct DOM element IDs for its sidebar implementation.
What happens if browser localStorage is cleared?
If the user clears browser data or localStorage is purged, the generation history will be permanently lost. Because the Open Generative AI repository implements no server-side persistence for this feature, the sidebar will initialize with an empty state (defaulting to '[]') on the next page load, as handled by the fallback logic at src/components/ImageStudio.js:1065.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →