Hi! I love Dayflow and use it daily. I'd like to contribute UI localization, and per the README's guidance on larger changes, I'm opening this issue first to agree on scope before sending PRs.
Motivation
The output-language override (from #141) works great for AI-generated summaries, but the UI chrome itself (sidebar, settings, onboarding, etc.) is hard-coded English. #281 also hints at demand for more language flexibility. I'm a native Korean speaker and would like to add proper UI localization with Korean as the first language - once the infrastructure is in place, other languages become community-contributable.
Proposed approach
Use Xcode's String Catalogs (Localizable.xcstrings), which the project is already set up for (LOCALIZATION_PREFERS_STRING_CATALOGS = YES and SWIFT_EMIT_LOC_STRINGS = YES are both on):
- String literals in SwiftUI views (
Text("..."), Button("..."), etc.) are extracted automatically at build time - no code changes needed for those. The compiler currently finds ~500 such strings.
- Strings born outside localization-aware positions (enum computed properties like
SidebarIcon.displayName, strings passed into the Settings design-system components' String parameters) get wrapped with String(localized:) - mechanical, greppable diffs.
- Untranslated keys fall back to English at runtime, so translations can land incrementally without ever breaking the UI.
- Maintenance cost for you stays near zero: any new literal you write shows up in the catalog on the next build, marked as needing translation.
Working proof of concept
Branch: https://github.com/SeongJaeSong/Dayflow/tree/feat/localization (commit b9213cf)
It localizes the main sidebar, the Settings tab titles, and the entire "Other" tab, with native-Korean translations. Built and verified by running the app with -AppleLanguages (ko):
| English (current) |
Korean (PoC) |
 |
 |
Suggested plan
- PR 1 - infrastructure + PoC scope (roughly the branch above): catalog +
ko region + sidebar/Settings demo. Small, reviewable.
- Follow-up PRs - full sweep by screen group (onboarding, timeline, journal, dialogs...): convert non-literal strings to
String(localized:) and complete the Korean translation. I'd batch these so each PR stays reviewable.
- Cleanups along the way: mark non-UI literals like
"ABC123" or format-only strings as non-localizable (Text(verbatim:)), and add comments to ambiguous keys (e.g. "Report") so translators get context.
A few open questions for you:
- Are you open to shipping localization at all? (Totally fine if you'd rather keep the surface English-only for now - closing this is a valid answer.)
- Any preference between
String(localized:) wrapping at call sites vs. changing the Settings component parameters to LocalizedStringKey? I went with the former to keep dynamic-string call sites untouched, but happy to do either.
- The UI follows the macOS system language (per-app override lives in System Settings > General > Language & Region). Would you also want an in-app language picker like the AI output override? I'd suggest keeping that out of scope initially.
If this direction works for you, I'll polish PR 1 right away.
Hi! I love Dayflow and use it daily. I'd like to contribute UI localization, and per the README's guidance on larger changes, I'm opening this issue first to agree on scope before sending PRs.
Motivation
The output-language override (from #141) works great for AI-generated summaries, but the UI chrome itself (sidebar, settings, onboarding, etc.) is hard-coded English. #281 also hints at demand for more language flexibility. I'm a native Korean speaker and would like to add proper UI localization with Korean as the first language - once the infrastructure is in place, other languages become community-contributable.
Proposed approach
Use Xcode's String Catalogs (
Localizable.xcstrings), which the project is already set up for (LOCALIZATION_PREFERS_STRING_CATALOGS = YESandSWIFT_EMIT_LOC_STRINGS = YESare both on):Text("..."),Button("..."), etc.) are extracted automatically at build time - no code changes needed for those. The compiler currently finds ~500 such strings.SidebarIcon.displayName, strings passed into the Settings design-system components'Stringparameters) get wrapped withString(localized:)- mechanical, greppable diffs.Working proof of concept
Branch: https://github.com/SeongJaeSong/Dayflow/tree/feat/localization (commit
b9213cf)It localizes the main sidebar, the Settings tab titles, and the entire "Other" tab, with native-Korean translations. Built and verified by running the app with
-AppleLanguages (ko):Suggested plan
koregion + sidebar/Settings demo. Small, reviewable.String(localized:)and complete the Korean translation. I'd batch these so each PR stays reviewable."ABC123"or format-only strings as non-localizable (Text(verbatim:)), and add comments to ambiguous keys (e.g. "Report") so translators get context.A few open questions for you:
String(localized:)wrapping at call sites vs. changing the Settings component parameters toLocalizedStringKey? I went with the former to keep dynamic-string call sites untouched, but happy to do either.If this direction works for you, I'll polish PR 1 right away.