Core Feature: Privacy-Focused Design
Relevant source files
The following files were used as context for generating this wiki page:
The application is architected as a static Single Page Application (SPA) with a strong emphasis on user privacy. This is achieved by exclusively using the browser's localStorage for all user-generated data and settings, eliminating the need for a backend database to store user information. All data, including image generation history and optional API tokens, remains on the user's client machine.
This client-centric approach ensures that user creations and configurations are not collected or stored on any server, providing a private and secure user experience. The application's code runs entirely in the browser, and interactions with external services are direct from the client to the respective APIs.
Architecture: Client-Side Data Storage
The core of the privacy-focused design is the reliance on the browser's localStorage API as the sole persistence layer for user data. This design choice means the application can function without a traditional backend server for user accounts or data management.
Data Storage Keys
All user-specific data is stored in localStorage under specific keys.
| Key | Description | Managed In |
|---|---|---|
ai_image_gen_history | An array of GeneratedImage objects, representing the user's creation history. | App.tsx |
huggingFaceToken | The user's optional Hugging Face API token for increased generation quotas. | components/SettingsModal.tsx |
app_language | The user's selected interface language ('en' or 'zh'). | App.tsx, components/SettingsModal.tsx |
Sources: App.tsx:44, App.tsx:93, components/SettingsModal.tsx:18
Local Storage Data Flow
The following diagram illustrates how the application interacts with localStorage during its lifecycle.
This diagram shows that all data is loaded from and saved to the browser's local storage, with no server-side interaction for data persistence.
Sources: App.tsx:43-48, App.tsx:92-105, App.tsx:117-123, components/SettingsModal.tsx:23-26
Image Generation History
Generated images and their associated metadata are saved as a history list. This entire history is stored locally.
Data Structure
Each entry in the history is an object conforming to the GeneratedImage interface.
| Field | Type | Description |
|---|---|---|
id | string | A unique identifier for the image, generated using crypto.randomUUID(). |
url | string | The URL of the generated image. |
prompt | string | The text prompt used to generate the image. |
aspectRatio | string | The aspect ratio of the image (e.g., "1:1"). |
timestamp | number | The Unix timestamp (in milliseconds) when the image was created. |
model | string | The model used for generation (e.g., 'z-image-turbo'). |
seed | number (optional) | The seed value used for generation. |
duration | number (optional) | The time taken to generate the image in seconds. |
isBlurred | boolean (optional) | A flag to indicate if the user has toggled a blur effect (for NSFW content). |
isUpscaled | boolean (optional) | A flag to indicate if the image has been upscaled. |
Sources: types.ts:3-14, services/hfService.ts:133, App.tsx:181-182
Data Retention Policy
To manage local storage space and maintain privacy, the application implements a simple data retention policy. On application startup, it filters the history and automatically discards any images that are older than one day (24 hours).
// App.tsx:92-105
const [history, setHistory] = useState<GeneratedImage[]>(() => {
try {
const saved = localStorage.getItem('ai_image_gen_history');
if (!saved) return [];
const parsedHistory: GeneratedImage[] = JSON.parse(saved);
const now = Date.now();
const oneDayInMs = 24 * 60 * 60 * 1000;
// Filter out images older than 1 day
return parsedHistory.filter(img => (now - img.timestamp) < oneDayInMs);
} catch (e) {
console.error("Failed to load history", e);
return [];
}
});
Sources: App.tsx:92-105
User Configuration Management
User settings, including the sensitive Hugging Face API token, are handled with the same client-side storage approach.
Hugging Face Token
Users can optionally provide their own Hugging Face API token to get higher rate limits. This token is managed exclusively on the client.
- The user enters the token in the
SettingsModal. - On save, the token is written to
localStorageunder the keyhuggingFaceToken. - When making an API call to a Hugging Face service, the
getAuthHeadersfunction reads the token fromlocalStorageand adds it to theAuthorizationheader of the outgoing request.
The token is never sent to any server other than the intended Hugging Face API endpoints.
The sequence diagram below shows the flow of retrieving and using the token.
This diagram illustrates that the token is stored and retrieved locally, and only used for direct communication with the Hugging Face API.
Sources: components/SettingsModal.tsx:23-26, services/hfService.ts:65-74
The getAuthHeaders function is responsible for retrieving the token and preparing the request headers.
// services/hfService.ts:65-74
const getAuthHeaders = (): Record<string, string> => {
const token = typeof localStorage !== 'undefined' ? localStorage.getItem('huggingFaceToken') : null;
const headers: Record<string, string> = {
"Content-Type": "application/json",
};
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
return headers;
};
Sources: services/hfService.ts:65-74
Conclusion
The privacy-focused design of this application is a fundamental architectural decision. By building a static SPA and leveraging the browser's localStorage for all data persistence, the system ensures that no user-specific data, including generated content and API keys, is ever stored on a central server. This client-side model gives users full control over their data, which is stored ephemerally (with a 1-day retention for history) on their own devices, maximizing privacy and security.