How to Configure FluentRead to Use Your Own AI API Keys: A Complete Guide
FluentRead stores AI API credentials in a local Config object with a token map that persists to browser storage, allowing you to configure custom keys through the settings UI or programmatically via the config.token interface.
FluentRead is an open-source browser extension that provides intelligent translation services using various AI providers. If you want to configure FluentRead to use your own AI API keys instead of default credentials, you need to understand how the extension manages authentication tokens across its architecture.
How FluentRead Stores API Credentials
The extension centralizes all configuration in a Config class defined in entrypoints/utils/model.ts. This class declares a token property as an IMapping type to hold string tokens for every service requiring authentication.
// entrypoints/utils/model.ts (lines 21-27)
export class Config {
service: string;
token: IMapping; // Stores API keys for each service
// ... other properties
}
When the extension initializes, entrypoints/utils/config.ts loads persisted settings from the browser's local storage and hydrates the exported config instance.
// entrypoints/utils/config.ts (lines 16-28)
const stored = await storage.getItem('local:config');
if (stored) {
const parsed = JSON.parse(stored as string);
Object.assign(config, parsed); // Merges stored tokens into config
}
This architecture ensures your API keys remain in local browser storage and never transit to external servers except when making direct API calls to your chosen AI provider.
Setting Up Your AI API Keys in FluentRead
Using the Settings UI
The primary interface for entering credentials resides in components/Main.vue. The UI binds an <el-input> element directly to config.token[config.service], creating a two-way data binding that updates the configuration object as you type.
<!-- components/Main.vue (lines 92-104) -->
<el-row v-show="compute.showToken" class="margin-bottom margin-left-2em">
<el-col :span="12" class="lightblue rounded-corner">
<span class="popup-text popup-vertical-left">访问令牌</span>
</el-col>
<el-col :span="12">
<el-input
v-model="config.token[config.service]"
type="password"
show-password
placeholder="请输入API访问令牌" />
</el-col>
</el-row>
To configure your key through the UI:
- Open the FluentRead extension panel in your browser.
- Select your desired AI service from the dropdown (e.g., OpenAI, Azure OpenAI, Gemini).
- Locate the "访问令牌" (Access Token) field.
- Paste your API key into the password input.
- The extension automatically persists the value to
local:configstorage.
Programmatic Configuration
For advanced users who want to inject credentials via userscripts or extension popups, you can manipulate the config object directly:
import { config } from '@/entrypoints/utils/config';
import { services } from '@/entrypoints/utils/option';
// Configure OpenAI API key programmatically
config.token[services.openai] = 'sk-your-openai-api-key';
// Persist immediately to local storage
await storage.setItem('local:config', JSON.stringify(config));
This approach is useful when distributing FluentRead in managed environments where you pre-configure keys for users.
Validating API Keys Before Translation
Before dispatching any translation request, FluentRead validates that required credentials exist. The checkConfig() function in entrypoints/utils/check.ts verifies token presence for services marked as requiring authentication.
// entrypoints/utils/check.ts (lines 10-18)
export function checkConfig(): boolean {
if (servicesType.isUseToken(config.service) && !config.token[config.service]) {
// Validation fails - token required but not provided
return false;
}
// Additional checks...
return true;
}
The servicesType.isUseToken() method checks membership in a Set defined in entrypoints/utils/option.ts that enumerates all token-requiring services.
// entrypoints/utils/option.ts (lines 69-78)
export const servicesType = {
useToken: new Set([
services.openai,
services.azureOpenai,
services.gemini,
services.anthropic,
services.deepseek,
services.moonshot,
services.siliconflow,
services.glm,
services.groq,
services.custom
])
};
If validation fails, FluentRead prompts the user to enter their API key before proceeding with the translation.
Adding Custom AI Services
You can extend FluentRead to support additional AI providers that require API keys by modifying three components:
First, register the new service in entrypoints/utils/option.ts:
// 1. Add to services enum
export const services = {
// ... existing services
myCustomAi: 'myCustomAi',
};
// 2. Add to token-requiring set
export const servicesType = {
useToken: new Set([
...servicesType.useToken,
services.myCustomAi
])
};
Next, implement the API client that reads the token from config.token:
// Custom service implementation example
import { config } from '@/entrypoints/utils/config';
import { services } from '@/entrypoints/utils/option';
export async function translateWithCustomAI(text: string) {
const apiKey = config.token[services.myCustomAi];
const response = await fetch('https://api.myservice.com/v1/chat', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4',
messages: [{ role: 'user', content: text }]
})
});
return response.json();
}
The existing UI in components/Main.vue automatically supports your new service because the token input binds to config.token[config.service] dynamically.
Key Files and Architecture Reference
| File | Role | Location |
|---|---|---|
entrypoints/utils/model.ts |
Declares the Config class and the token map property. |
model.ts |
entrypoints/utils/config.ts |
Loads and persists the Config instance from local browser storage. |
config.ts |
entrypoints/utils/option.ts |
Defines available services and identifies which require tokens via servicesType.useToken. |
option.ts |
entrypoints/utils/check.ts |
Validates token presence before translation requests via checkConfig(). |
check.ts |
components/Main.vue |
Provides the settings UI where users input API keys bound to config.token. |
Main.vue |
Summary
- FluentRead uses a centralized
Configclass with atokenmap to store API keys for each AI service inentrypoints/utils/model.ts. - Credentials persist in browser local storage via
entrypoints/utils/config.ts, ensuring keys remain private to your machine. - The settings UI in
components/Main.vuebinds directly toconfig.token[config.service], providing real-time updates and automatic persistence. - Validation occurs before translation through
checkConfig()inentrypoints/utils/check.ts, which verifies tokens exist for services listed inservicesType.useToken. - You can extend support for new AI providers by adding entries to
entrypoints/utils/option.tsand implementing the corresponding API client.
Frequently Asked Questions
Where does FluentRead store my API keys?
FluentRead stores your API keys in the browser's local storage under the key local:config. The Config class in entrypoints/utils/model.ts defines a token property that maps service names to their corresponding API keys. When you enter a key in the settings UI, it writes directly to config.token[config.service] and persists via storage.setItem('local:config', JSON.stringify(config)), ensuring your credentials never leave your local machine except when making direct API calls to your chosen AI provider.
Can I use multiple AI providers simultaneously with different API keys?
Yes, FluentRead supports multiple AI providers simultaneously through the token map structure. Each service defined in entrypoints/utils/option.ts—such as services.openai, services.gemini, or services.anthropic—maintains its own entry in config.token. You can configure a unique API key for each provider through the settings panel, and FluentRead will use the corresponding token based on whichever config.service is currently selected for translation.
How do I add a custom AI service that requires an API key?
To add a custom AI service, modify three files in the FluentRead source. First, add your service identifier to the services object in entrypoints/utils/option.ts. Second, add the service to the servicesType.useToken Set to indicate it requires authentication. Third, implement the API client in a new service file, reading the key via config.token[services.yourService]. The existing UI in components/Main.vue will automatically display the token input field for your new service because it dynamically binds to config.token[config.service].
What happens if my API key is invalid or missing?
Before sending any translation request, FluentRead executes checkConfig() in entrypoints/utils/check.ts to validate the configuration. If the selected service is listed in servicesType.useToken (defined in entrypoints/utils/option.ts) and config.token[config.service] is empty or undefined, the validation fails and FluentRead prompts you to enter your API key. The translation request will not proceed until a valid token is provided, preventing unnecessary API errors and ensuring you know exactly which service requires authentication.
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 →