flutter_localization_updater 1.0.9
flutter_localization_updater: ^1.0.9 copied to clipboard
A Flutter package that automatically updates localizations from Google Sheets and integrates with easy_localization.
flutter_localization_updater #
A Flutter package that automatically updates localizations from Google Sheets and integrates seamlessly with easy_localization.
Features #
- 🔄 Automatic Updates: Fetch translations from Google Sheets automatically
- 📱 Easy Integration: Works with
easy_localizationout of the box - ⏰ Smart Caching: Configurable update intervals to avoid unnecessary API calls
- 🌍 Multi-language Support: Support for multiple locales
- 📁 Dynamic Loading: Load translations from both bundled assets and dynamically updated files
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_localization_updater: ^1.0.9
Setup #
1. Google Sheets API Setup #
- Go to the Google Cloud Console
- Create a new project or select an existing one
- Enable the Google Sheets API
- Create credentials (API Key)
- Create a Google Sheet with your translations
2. Google Sheet Structure #
Your Google Sheet should have the following structure:
| Key | en | nl | es |
|---|---|---|---|
| general_header_title | Welcome | Welkom | Bienvenido |
| general_searching_location | Searching location... | Locatie zoeken... | Buscando ubicación... |
3. Create Localization Files #
Before setting up the localization service, you need to create the initial JSON files for your supported locales. You can do this manually or use the provided command-line tool:
# Create default localization files (en, nl)
dart run flutter_localization_updater:localize
# Create files for specific locales
dart run flutter_localization_updater:localize --locales=en,nl,fr,es
# Specify custom output directory
dart run flutter_localization_updater:localize --output-dir=assets/translations
# Use a custom template file
dart run flutter_localization_updater:localize --template-file=my_template.json
This will create JSON files with translations fetched from your Google Sheets. The files will be created in assets/localizations/ by default (e.g., en.json, nl.json).
Command Options:
--locales, -l: Comma-separated list of locale codes (default: en,nl)--output-dir, -o: Output directory for localization files (default: assets/localizations)--template-file, -t: Path to a template JSON file to use as base
Google Sheets Integration: The command automatically fetches translations from your Google Sheets if you set the following environment variables:
GOOGLE_SHEETS_API_KEY: Your Google Sheets API keyGOOGLE_SHEET_ID: The ID of your Google Sheet (found in the URL)GOOGLE_SHEET_NAME: The name of the specific tab/sheet to use (optional, processes all tabs if not specified)
You can set these variables in several ways:
-
Using a
.envfile (recommended):# Create a .env file in your project root GOOGLE_SHEETS_API_KEY=your_api_key_here GOOGLE_SHEET_ID=your_sheet_id_here GOOGLE_SHEET_NAME=your_tab_name_here -
Using system environment variables:
# On Windows PowerShell: $env:GOOGLE_SHEETS_API_KEY="your_api_key_here" $env:GOOGLE_SHEET_ID="your_sheet_id_here" $env:GOOGLE_SHEET_NAME="your_tab_name_here" # On Linux/Mac: export GOOGLE_SHEETS_API_KEY="your_api_key_here" export GOOGLE_SHEET_ID="your_sheet_id_here" export GOOGLE_SHEET_NAME="your_tab_name_here"
If no specific sheet name is provided, the command will process all available tabs and combine their translations.
Tab Name Prefixing: Property names are automatically prefixed with the tab name and an underscore. Dots in keys are converted to underscores, and all keys are converted to lowercase. For example:
-
Tab name: "Auth"
-
Key in sheet: "LoginButton"
-
Result in JSON:
{"auth_loginbutton": "Login"} -
Tab name: "Auth"
-
Key in sheet: "General.LoginButton"
-
Result in JSON:
{"auth_general_loginbutton": "Login"} -
Tab name: "Profile"
-
Key in sheet: "Settings.Notifications.Email"
-
Result in JSON:
{"profile_settings_notifications_email": "Email notifications"}
If these environment variables are not set, the command will create files with template content that you can fill in manually.
Google Sheet Structure: Your Google Sheet should have the following structure:
| Key | en | nl | es |
|---|---|---|---|
| general_header_title | Welcome | Welkom | Bienvenido |
| general_searching_location | Searching location... | Locatie zoeken... | Buscando ubicación... |
The first column should contain the translation keys (using dot notation for nested structures), and subsequent columns should contain translations for each locale.
4. Basic Usage #
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_localization_updater/flutter_localization_updater.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize localization service with timeout
final localizationService = LocalizationService(
config: LocalizationConfig(
googleSheetApiKey: 'YOUR_GOOGLE_SHEETS_API_KEY',
sheetId: 'YOUR_GOOGLE_SHEET_ID',
supportedLocales: ['en', 'nl', 'es'],
updateIntervalMs: 24 * 60 * 60 * 1000, // 24 hours
timeout: Duration(seconds: 10), // 10 seconds timeout
),
);
// Option 1: Wait for update with timeout (recommended for app startup)
final success = await localizationService.checkAndUpdateLocalizations();
if (!success) {
print('Translation update timed out or failed, continuing with cached data');
}
// Option 2: Start background update (use this if you want app to start immediately)
// localizationService.startBackgroundUpdate();
// Initialize easy_localization
await EasyLocalization.ensureInitialized();
runApp(EasyLocalization(
supportedLocales: const [Locale('en'), Locale('nl'), Locale('es')],
path: 'assets/localizations',
fallbackLocale: const Locale('en'),
assetLoader: CustomAssetLoader(), // Use the custom asset loader
child: MyApp(),
));
}
API Reference #
LocalizationConfig #
Configuration class for the localization service.
LocalizationConfig({
required String googleSheetApiKey,
required String sheetId,
String baseUrl = "https://sheets.googleapis.com/v4/spreadsheets/",
int updateIntervalMs = 24 * 60 * 60 * 1000, // 24 hours
List<String> supportedLocales = const ['en', 'nl'],
String lastUpdateKey = 'last_localization_update',
Duration timeout = const Duration(seconds: 5), // 5 seconds default timeout
})
Parameters:
googleSheetApiKey: Your Google Sheets API keysheetId: The ID of your Google Sheet (found in the URL)baseUrl: Base URL for Google Sheets API (usually don't change this)updateIntervalMs: How often to check for updates (in milliseconds)supportedLocales: List of supported locale codeslastUpdateKey: Key for storing last update timestamptimeout: Maximum time to wait for translation updates before continuing
LocalizationService #
Main service class for managing localizations.
LocalizationService({
required LocalizationConfig config,
Dio? dio,
})
Methods:
updateLocalizations(): Force update localizations from Google Sheets (returnsFuture<bool>)checkAndUpdateLocalizations(): Check if update is needed and update if necessary (returnsFuture<bool>)startBackgroundUpdate(): Start update in background without blocking the appshouldUpdateLocalizations(): Check if localizations need updatinggetLocalizationsPath(): Get the path to localizations directory
Timeout and Background Updates #
The service now includes timeout functionality to prevent your app from hanging while waiting for translations:
// Configure timeout (default is 5 seconds)
final localizationService = LocalizationService(
config: LocalizationConfig(
googleSheetApiKey: 'YOUR_API_KEY',
sheetId: 'YOUR_SHEET_ID',
timeout: Duration(seconds: 15), // Custom timeout
),
);
// Option 1: Wait for update with timeout (app continues after timeout)
final success = await localizationService.checkAndUpdateLocalizations();
if (!success) {
print('Translation update timed out or failed, continuing with cached data');
}
// Option 2: Start background update (app continues immediately)
localizationService.startBackgroundUpdate();
Timeout Behavior:
- If the translation update takes longer than the configured timeout, the app will continue with cached/local translations
- The update will continue in the background even after timeout
- Network requests are also timed out to prevent hanging connections
- Failed updates are logged but don't crash the app
CustomAssetLoader #
Custom asset loader for easy_localization that loads from both bundled assets and dynamically updated files.
CustomAssetLoader()
Example #
See the example/ directory for a complete working example.
Contributing #
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License #
This project is licensed under the MIT License - see the LICENSE file for details.