How to Internationalize and Localize Palmier Pro

To internationalize Palmier Pro, replace hard-coded UI strings with localization keys in SwiftUI, create .lproj directories containing Localizable.strings files for each target language, and leverage the existing Locale handling in CaptionTab for caption language support.

Palmier Pro is an open-source video editing application that currently ships with hard-coded English strings in its SwiftUI interface. While the captioning pipeline already supports multiple languages via Transcription.supportedLocales(), the user interface itself requires systematic externalization of strings to support a global audience. This guide walks you through the complete localization process based on the actual source code architecture in the palmier-io/palmier-pro repository.

Understanding the Current Localization Architecture

Before adding new languages, examine the existing internationalization foundations already present in the codebase.

Existing Locale Support in CaptionTab

The CaptionTab.swift file at Sources/PalmierPro/MediaPanel/CaptionsTab/CaptionTab.swift already implements language-aware captioning. It stores the selected locale in a state variable named locale and passes this to the caption generation pipeline. The view model uses this value when constructing CaptionRequest objects in EditorViewModel+Captions.swift.

Additionally, the Transcription.swift file provides supportedLocales() to list available caption languages, and uses Locale.current.localizedString(forIdentifier:) to display human-readable language names. This infrastructure handles backend localization, but the UI layer remains hard-coded.

Package.swift Resource Configuration

The Package.swift file already includes the Resources folder in its target resources array. This means any Localization subdirectories you create will be automatically bundled into the application without modifying the build configuration.

Step-by-Step Internationalization Implementation

Follow these steps to convert the English-only interface into a fully localized application.

Step 1: Create Localization Directory Structure

Create the base directory structure for your source language and any target languages:

mkdir -p Sources/PalmierPro/Resources/Localization/en.lproj
mkdir -p Sources/PalmierPro/Resources/Localization/es.lproj
touch Sources/PalmierPro/Resources/Localization/en.lproj/Localizable.strings
touch Sources/PalmierPro/Resources/Localization/es.lproj/Localizable.strings

Commit the English Localizable.strings file as your source of truth. This file uses key-value pairs where the key is a stable identifier and the value is the English text.

Step 2: Replace Hard-Coded Strings with Localization Keys

In CaptionTab.swift and other SwiftUI views, replace string literals with localization keys. SwiftUI automatically treats string literals in Text initializers as LocalizedStringKey.

Convert buttons and labels from hard-coded strings:

// Before
Button(action: generate) {
    Text("Generate Captions")
}

// After
Button(action: generate) {
    Text("generate_captions_btn")
}

Then add the corresponding entry to en.lproj/Localizable.strings:

"generate_captions_btn" = "Generate Captions";

Apply this pattern to all user-facing strings, including alert messages, navigation titles, and Label components throughout the codebase.

Step 3: Add Language-Specific Strings Files

For each additional language, create a matching .lproj directory with a Localizable.strings file. For example, add Spanish translations in es.lproj/Localizable.strings:

"generate_captions_btn" = "Generar subtítulos";
"my_projects_title" = "Mis proyectos";
"error_captions_failed" = "Error al generar subtítulos";

For pluralization or complex formatting rules, create a Localizable.stringsdict file in the same directory alongside your Localizable.strings file.

Step 4: Handle Non-SwiftUI Components

For error messages or strings used outside SwiftUI views (such as in Transcription.swift or view models), create a helper extension to wrap NSLocalizedString:

extension String {
    /// Returns a localized version of the string using the key itself.
    var localized: String {
        NSLocalizedString(self, comment: "")
    }
}

Usage in non-UI code:

let errorMessage = "error_captions_failed".localized

This ensures consistency across the entire application, including backend error handling and logging messages.

Step 5: Configure Build Settings

Since Package.swift already includes the Resources folder in its resources array, the new localization files will be bundled automatically. However, verify that Xcode recognizes your localization by:

  1. Opening the project in Xcode
  2. Selecting the project file
  3. Ensuring the localization languages appear under the "Localizations" section
  4. Checking that the Localizable.strings files are included in the target membership

Key Source Files and Their Roles

Understanding these specific files helps you navigate the localization changes:

  • Sources/PalmierPro/MediaPanel/CaptionsTab/CaptionTab.swift – Contains the locale state variable and the languageName() helper function that uses Locale.current.localizedString(forIdentifier:). This file requires the most UI string replacements.
  • Sources/PalmierPro/Transcription/Transcription.swift – Provides supportedLocales() and manages language display names for the captioning pipeline.
  • Sources/PalmierPro/Editor/ViewModel/EditorViewModel+Captions.swift – Passes the selected Locale to the caption generation request.
  • Package.swift – Declares resource bundles, ensuring localization files are packaged with the app.

Testing Your Localization

Verify your implementation using Xcode's scheme settings:

  1. Select "Product" → "Scheme" → "Edit Scheme"
  2. Choose "Options"
  3. Set "Application Language" to your target language (e.g., Spanish)
  4. Run the application

Alternatively, launch the app from the command line with the -AppleLanguages argument:

./PalmierPro -AppleLanguages "(es)"

Check for truncated text, layout issues with longer translations, and ensure that the CaptionTab locale selector remains functional and properly localized.

Summary

  • Palmier Pro already supports caption language selection via Locale in CaptionTab.swift and Transcription.swift.
  • Externalize strings by replacing hard-coded literals with keys in Text() views and using a String.localized extension for non-SwiftUI code.
  • Create .lproj directories for each language under Sources/PalmierPro/Resources/Localization/.
  • Maintain Localizable.strings files for each language, adding Localizable.stringsdict for pluralization rules.
  • Test thoroughly using Xcode's scheme language settings to verify UI layout and functionality across all supported locales.

Frequently Asked Questions

How do I add a new language to Palmier Pro?

Create a new language directory following the pattern Sources/PalmierPro/Resources/Localization/[language-code].lproj/, where [language-code] is a valid BCP 47 identifier (e.g., fr for French, de for German). Copy the Localizable.strings file from en.lproj, translate the values while keeping the keys identical, and commit the new directory. The Package.swift configuration automatically bundles these resources.

Does Palmier Pro support runtime language switching?

The current architecture uses system locale detection by default. For runtime switching, you must store the user-selected language code in UserDefaults and override Bundle.main.preferredLocalizations before the UI loads. The CaptionTab already stores a locale property for caption language, which you can extend to drive the entire app's language selection.

What is the difference between caption language and UI language?

The caption language determines which language is used for generated video captions and subtitles, controlled by the locale property in CaptionTab.swift and passed to EditorViewModel+Captions.swift. The UI language controls the text displayed in buttons, labels, and menus, which is determined by the Localizable.strings files. These can be independent—for example, a user might run the app in English but generate Spanish captions.

How do I handle pluralization in Palmier Pro localizations?

For strings requiring pluralization (e.g., "1 project" vs "5 projects"), create a Localizable.stringsdict file in your .lproj directory. This XML-formatted file defines rules for different plural categories (zero, one, two, few, many, other) that iOS evaluates at runtime. Standard Localizable.strings entries cannot handle dynamic counts, so use .stringsdict for any user-facing strings that include numbers.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →