Common Issues
This guide covers the most common issues you might encounter and how to resolve them.
Initialization Issues
Strings show '??key??' instead of translations
Problem: Strings display as ??welcome_message?? instead of actual contentPossible Causes:
SDK not initialized
String key doesn’t exist in backend
Network sync hasn’t completed
Invalid API token
Solutions: // 1. Check if SDK is initialized
console . log ( 'SDK initialized:' , StringBoot . isReady );
// 2. Trigger manual sync
try {
await StringBoot . syncNow ();
} catch ( error ) {
console . error ( 'Sync failed:' , error );
}
// 3. Check if key exists
const text = await StringBoot . get ( 'welcome_message' );
if ( text . startsWith ( '??' )) {
console . error ( 'String not found:' , text );
}
// 4. Verify API token in initialization
await StringBoot . initialize ({
apiToken: 'verify-this-is-correct' ,
baseUrl: 'https://api.stringboot.com'
});
// 1. Check initialization
if ( ! StringProvider. isInitialized ()) {
StringbootExtensions. autoInitialize ( this )
}
// 2. Trigger manual sync
lifecycleScope. launch {
val success = StringProvider. refreshFromNetwork ( "en" )
Log. i ( "Stringboot" , "Sync success: $success " )
}
// 3. Verify key exists in dashboard
// 4. Check API token in AndroidManifest.xml
// 1. Check if SDK is ready
if ! stringProvider.isReady {
print ( "SDK not ready" )
}
// 2. Check for initialization errors
if let error = stringProvider.initializationError {
print ( "Init error: \( error ) " )
}
// 3. Trigger manual sync
Task {
await stringProvider. refreshFromNetwork (
lang : "en" ,
forceRefresh : true
)
}
Problem: SDK fails to initialize or gets stuck in loading stateCommon Causes:
Invalid API token
Wrong baseURL
Network firewall blocking requests
Missing internet permission (mobile)
Solutions: Web: try {
await StringBoot . initialize ({
apiToken: 'check-this-token' ,
baseUrl: 'https://api.stringboot.com' , // Check URL is correct
defaultLanguage: 'en' ,
debug: true // Enable for more info
});
} catch ( error ) {
console . error ( 'Init error:' , error );
// Check browser console for details
}
Android: <!-- Verify AndroidManifest.xml -->
< uses-permission android:name = "android.permission.INTERNET" />
< meta-data
android:name = "com.stringboot.api_url"
android:value = "https://api.stringboot.com" />
< meta-data
android:name = "com.stringboot.api_token"
android:value = "YOUR_VALID_TOKEN" />
iOS: // Enable logging to see what's happening
StringbootLogger. isLoggingEnabled = true
StringbootLogger. logLevel = . debug
StringProvider. shared . initialize (
cacheSize : 1000 ,
apiToken : "verify-this-token" ,
baseURL : "https://api.stringboot.com" ,
autoSync : true
)
Problem: App takes too long to load strings on first launchCause: Cache is cold, requires network fetchSolution: Preload strings synchronously// Preload during initialization
await StringBoot . initialize ({ /* config */ });
// Preload top strings
await StringBoot . syncNow ();
// In Application.onCreate()
runBlocking {
val locale = StringProvider. deviceLocale ()
StringProvider. preloadLanguage (locale, maxStrings = 500 )
}
// In App init
StringProvider. shared . initialize ( ... )
// Restore saved language before showing UI
let savedLang = UserDefaults. standard . string (
forKey : "com.stringboot.currentLanguage"
) ?? StringProvider. shared . deviceLocale ()
StringProvider. shared . setLocale (savedLang)
Language Switching Issues
Strings don't update after language change
Problem: UI still shows old language after calling changeLanguage()Cause: UI not reacting to language changesSolutions: Web (Vanilla JS)
Web (React)
Android
iOS
// Use watchers for automatic updates
StringBoot . watch ( 'welcome_message' , ( value ) => {
document . getElementById ( 'welcome' ). textContent = value ;
});
// Then language change updates automatically
await StringBoot . changeLanguage ( 'es' );
// Use hooks instead of manual state
function Component () {
const title = useString ( 'app_title' ); // Auto-updates!
return < h1 > { title } </ h1 > ;
}
// Re-apply tags after language change
private fun switchLanguage (newLang: String ) {
lifecycleScope. launch {
StringProvider. setLocale (newLang)
StringProvider. preloadLanguage (newLang, 500 )
// Must re-apply tags!
withContext (Dispatchers.Main) {
binding.root. applyStringbootTags ()
}
}
}
// Use @ObservedObject
@ObservedObject var stringProvider = StringProvider. shared
// Or use SBText which updates automatically
SBText ( "welcome_message" )
Language picker triggers multiple times
Problem: Language change function called repeatedlyCause: UI not disabled during language changeSolution: languageSelect . addEventListener ( 'change' , async ( e ) => {
languageSelect . disabled = true ; // Disable during change
try {
await StringBoot . changeLanguage ( e . target . value );
} finally {
languageSelect . disabled = false ; // Re-enable
}
});
Picker ( "Language" , selection : $selectedLanguage) {
// ...
}
. disabled (stringProvider. isChangingLanguage ) // Disable during change
Flash of old content when changing language
Problem: Brief flash of old language before new language appearsCause: Cache is cold for new languageSolution: Preload language before switching// Android
lifecycleScope. launch {
StringProvider. setLocale ( "es" )
StringProvider. preloadLanguage ( "es" , maxStrings = 500 ) // Prevent flash
binding.root. applyStringbootTags ()
}
// iOS
await StringProvider. shared . changeLanguage ( to : "es" )
// SDK automatically preloads
Module not found error Problem: Cannot find module '@stringboot/web-sdk'Solution: # Reinstall package
npm install @stringboot/web-sdk
# Clear cache if needed
rm -rf node_modules package-lock.json
npm install
React hooks not working Problem: Hooks don’t update or crashSolution: // Must initialize SDK before using hooks
function App () {
const { initialized } = useStringBoot ({
apiToken: 'token' ,
baseUrl: 'url'
});
if ( ! initialized ) return < Loading /> ;
// Now safe to use other hooks
return < MainContent /> ;
}
CORS errors Problem: Browser blocks requests to Stringboot APISolution:
Verify baseUrl is correct: https://api.stringboot.com
Check that you’re not using http:// instead of https://
Contact support if CORS errors persist
IndexedDB errors Problem: “Failed to open IndexedDB”Solution:
Check if private browsing is enabled (not supported)
Verify browser version meets minimum requirements
Clear browser data and try again
ProGuard/R8 issues Problem: App crashes in release buildSolution: # Add to proguard-rules.pro
-keep class com.stringboot.sdk.** { *; }
-keepclassmembers class com.stringboot.sdk.** { *; }
Room database migration errors Problem: “Migration didn’t properly handle…”Solution: // Clear app data and reinstall
// Or clear language cache
StringProvider. clearLanguageCache ( "en" )
Problem: Tags not applying to TextViewsSolution: <!-- Verify android:tag is set -->
< TextView
android:id = "@+id/myTextView"
android:tag = "my_string_key" <!-- Required! -- >
android:text="@string/my_string_key" />
// Call after setContentView
setContentView (binding.root)
binding.root. applyStringbootTags () // Must be after setContentView
Strings not loading on API 24-26 Problem: Older Android versions not workingSolution:
Verify minSdk is 24 or higher
Test on actual device, not just emulator
Enable logging to see what’s happening
Memory leaks Problem: App memory usage grows over timeSolution: // Cancel coroutines in onDestroy
override fun onDestroy () {
super . onDestroy ()
languageDisplayJob?. cancel ()
}
// Use lifecycleScope, not GlobalScope
lifecycleScope. launch { // ✓ Good
// ...
}
GlobalScope. launch { // ✗ Bad
// ...
}
SwiftUI previews not working Problem: Previews crash or show errorsSolution: struct ContentView_Previews : PreviewProvider {
static var previews: some View {
// Initialize SDK for preview
let _ = StringProvider. shared . initialize (
cacheSize : 100 ,
apiToken : "preview-token" ,
baseURL : "https://api.stringboot.com" ,
autoSync : false
)
ContentView ()
}
}
View doesn’t update after language change Problem: Text stays in old languageSolution: // Must use @ObservedObject
@ObservedObject var stringProvider = StringProvider. shared // ✓
// Not this:
let stringProvider = StringProvider. shared // ✗
Core Data errors Problem: “Core Data migration failed”Solution: // Clear cache and restart
stringProvider. clearCache ( clearDatabase : true )
// Restart app
exit ( 0 ) // Only for debugging
Simulator vs Device behavior differences Problem: Works in simulator but not on deviceSolution:
Test on actual device early
Check device iOS version meets minimum (14.0+)
Verify internet permission (should work automatically)
Memory warnings Problem: App crashes with memory warningSolution: // SDK handles didReceiveMemoryWarning automatically
// But you can manually reduce cache if needed
stringProvider. clearCache ( clearDatabase : false )
Network and Connectivity
Sync fails with network error
Problem: “Network error” or “Request failed”Checklist: Test Connection: # Test from command line
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://api.stringboot.com/strings/meta
Problem: Sync takes >30 secondsPossible Causes:
Slow network connection
Large number of strings
Server issues
Solutions:
Use delta sync (enabled by default)
Preload during app initialization
Sync in background, don’t wait for completion
Check server status
Problem: App using too much dataCheck: // Verify you're not force-refreshing too often
await StringBoot . syncNow (); // ✓ Good - uses ETag
await StringBoot . forceRefresh (); // ✗ Bad if done frequently
Best Practice:
Let SDK handle automatic sync
Only force-refresh when user explicitly requests
Use delta sync (default)
Debugging Tips
Enable Debug Logging
await StringBoot . initialize ({
apiToken: 'token' ,
debug: true // Logs all operations
});
Check Cache Stats
const stats = await StringBoot . getCacheStats ();
console . log ( 'Cache stats:' , stats );
// {
// memory: { size: 42, maxSize: 1000 },
// db: { totalStrings: 150, deletedStrings: 3 }
// }
Test Offline Behavior
Enable airplane mode
Force quit app
Relaunch app
Verify : App should load all previously synced strings from cache
Inspect Network Requests
Web (Chrome DevTools):
Open DevTools → Network tab
Filter by “stringboot” or API domain
Check request/response details
Android (Logcat):
adb logcat | grep "OkHttp\|Stringboot"
iOS (Console App):
Connect device
Open Console app on Mac
Filter by “Stringboot” or “URLSession”
Still Having Issues?
When Reporting Issues
Include the following information:
Platform and version (Web/Android/iOS)
Error messages and stack traces
Expected vs actual behavior
Network conditions when issue occurred
Next Steps