Output Directory

The CLI outputs data from Ditto by writing files to disk. By default, these files are written to a ./ditto folder relative to the current working directory, but the location of the output files can be customized by setting the environment variable DITTO_TEXT_DIR.

If a DITTO_TEXT_DIR environment variable is specified, the config will still be read from a ./ditto folder relative to the current working directory that the CLI is executing in.

./ditto Directory

This directory houses the configuration file (./ditto/config.yml) used by the CLI and is also the default write destination for any output files the CLI writes to disk.

If you run the CLI in a directory that does not contain a ditto/ folder, the folder and a default config.yml file will be automatically created.

String File Naming Conventions

All string files created will adhere to the following template:

{source_name}__{variant_name}.{extension}
  • source_name: the name of the source a given file holds data for
    • for components, this is components__{folder_name}
    • for projects, this is {project-name}
  • variant_name: the API ID of a variant or base for files generated for non-variant text
  • extension: the file extension that corresponds to the configured format(s)

To keep cross-platform behavior consistent, file names will be fully lowercase, have whitespace replaced with hyphens, and have non-word characters (with the exception of - and _) removed.

See the section on iOS format-specific files for the only exception to these conventions.

Format-specific Files

JSON

If one or more JSON string formats are configured, an index.js driver file is generated to simplify the process of integrating Ditto into JavaScript apps.

If a package.json file is detected with "type": "module", the driver file will be generated as an ESM module. Otherwise, it will be generated as a CommonJS module.

// CommonJS
const componentsRootBase = require("./components__root__base.json");
const componentsRootSpanish = require("./components__root__spanish.json");
const exampleProjectBase = require("./example-project__base.json");
const exampleProjectSpanish = require("./example-project__spanish.json");

module.exports = {
  ditto_component_library: {
    base: { ...componentsRootBase },
    spanish: { ...componentsRootSpanish },
  },
  project_xxx: {
    base: { ...exampleProjectBase },
    spanish: { ...exampleProjectSpanish },
  },
};

// ESM
import componentsRootBase from "./components__root__base.json";
import componentsRootSpanish from "./components__root__spanish.json";
import exampleProjectBase from "./example-project__base.json";
import exampleProjectSpanish from "./example-project__spanish.json";

export default {
  ditto_component_library: {
    base: { ...componentsRootBase },
    spanish: { ...componentsRootSpanish },
  },
  project_xxx: {
    base: { ...exampleProjectBase },
    spanish: { ...exampleProjectSpanish },
  },
};

To enable easy Typescript compatibility, an index.d.ts file is also generated with type definitions for the driver file.

The generation of both the index.js and index.d.ts files can be disabled by specifying disableJsDriver: true in your config.yml file.

iOS

If one or more iOS string formats (ios-strings, ios-stringsdict) are configured alongside the iosLocales property, iOS string files are grouped into localization bundles and a Ditto.swift driver file is generated.

The string files will be structured as follows:

ditto/
├── en.lproj/
│   ├── components.strings
│   ├── project1.strings
├── es.lproj/
│   ├── components.strings
│   ├── project1.strings

The Ditto.swift driver file will look like this:

//
// Ditto.swift
//
// Created by the Ditto CLI on 10/6/2023, 1:16:52 PM
//

import SwiftUI

struct Ditto {
  public static func component1(_ localeOverride: String? = nil) -> String {
    String.localizedStringWithFormat(NSLocalizedString("component-1", tableName: "components", /* ... */))
  }

  public struct project1 {
    public static func textItem1(_ localeOverride: String? = nil, variable1: String) -> String {
      String.localizedStringWithFormat(NSLocalizedString("text-item-1", tableName: "project1", /* ... */), variable1)
    }
  }

These files are designed to be imported into Xcode by reference. This enables using the CLI to pull the latest strings from Ditto and have the text in your project automatically updated.

To add these files to your Xcode project:

  1. Open Finder and select all .strings and .stringsdict files inside of the respective lproj folders.
  2. Drag the selected files into your Xcode project.
  3. When prompted, select Create folder references and deselect Copy if needed.
  4. Click Finish.

Once all your localization bundles and Ditto.swift driver are imported into Xcode, you can call methods from the Ditto struct directly to get localized strings:

struct ContentView: View {
  var body: some View {
    Text(Ditto.component1())
    Text(Ditto.textItem1(variable1: "Hello world!"))
  }
}