1. Help Center
  2. End-to-end guides

How does Phrase work with files, and how do I keep my file structure?

Learn how Phrase works with localization files, and how to keep the original file structure when uploading your files into a project.

By default, Phrase stores translatable resources as keys and values instead of keeping the original file structure. However, some frameworks or setups require multiple source files, and in turn, additional configuration in Phrase. But first, let's have a look at the benefits of the approach we are following.

Keeping file uploads and downloads as flexible as possible

This way of dealing with localization data has some mayor advantages:

  • File formats are interchangeable: You can upload iOS Localizable strings files into your project and download the same data for in Android XML or Gettext format - or both. There is no lock-in regarding the format! See our our full list of formats we support.
  • Flexible Grouping: Instead of deciding which keys you want to store in which file, you can group your translation keys/resources in a flexible way with our tagging system.


When you upload a file into a project, we will extract all new resources from that file and store them in your project. The uploaded file's format does not have to be the format you set up your project with in the first place. If you provided tags for grouping your resources, we will tag all your new keys with those tags. For more information about all available options, please see our article on uploading localization files.

Some formats such as Gettext provide additional valuable meta information such as comments, descriptions, or information about pluralization. We extract that information when- and wherever possible and store it along with your resources, allowing us to save all the valuable information you already provided in your localization files for further use.


At some point, you might want to get your (translated) localization files back to review them or deploy them with your new feature or updated application. Once you download the files from Phrase, we will generate a completely new file for you from scratch in the format you requested. Although this file can look different from the one initially uploaded, we will always make sure that it is a valid localization file and that includes all relevant metadata you provided in the first place.

While the specific file structure might differ from your original one (e.g. the sorting of the translation keys within the file), we will always give you a valid file to work with and deploy with your application. For further information, please see our article on downloading localization files.

Keeping separate files

In general, we encourage to keep all translations for each language in one file instead, since this makes downloading the resources from Phrase faster and more robust in the process. Plus, the Phrase Translation Center will keep your translations organized for you so that you don’t have to keep separate files around to find translations.

However, if you do require keeping localization information in separate files, Phrase supports file-based workflows. The way to achieve this is by tagging your keys with the correct tags during the initial upload and referencing those tags when downloading translations from your project back into the file(s) they came from. Keys can have multiple tags and can therefore be included in multiple files if required.  The tag-based workflow is extremely flexible and lets you re-organize your translation resources without having to re-upload files into your project at all.

In order for this process to work smoothly, keys should have unique names across all your files. In a key-value-based approach, a key needs to have the same values assigned to it in every context. Some frameworks allow you to use non-unique keys over multiple files. Some formats like Symfony support message domains. These domains are detected by the filename. Please note that Phrase will not automatically scope your keys by filename-based domains. You can resolve this by using a unique domain prefix for keys within the file.

Example configuration for Phrase CLI client

If you are working with our Phrase CLI client or connecting a project with your repository (e.g. GitHub, GitLab, or Bitbucket) then you need to set up a configuration file to manage your up- and downloads. Please see the example below on how to tackle this for a setup with multiple files.

In our example, a project has several semantically named translation files for the source locale. For example: “accounts.en.yml”, “emails.en.yml” etc. These semantic names are going to be managed through tags in Phrase.

Configure your .phrase.yml to reflect the organization of the files in your project and link them to tags in the Phrase project by including the tag placeholder in the file path. 

  access_token: "3d7e6598d955bfcab104c45c40af1b9459df5692ac4c28a17793"
  project_id: "23485c9c5dfb15d85b32d9c5f3d2hl54"
  file_format: yml
      - file: ./path/to/locales/<tag>.en.yml
          locale_id: "abcd1234cdef1234abcd1234cdef1234"
      # accounts
      - file: ./path/to/locales/accounts.<locale_name>.yml
        tags: accounts
      # emails
      - file: ./path/to/locales/emails.<locale_name>.yml
        tags: emails

You can also use the parameter tags in the push section instead of using the <tag>  placeholder.

The configuration above will create keys with tags based on the file they came from when running phrase push or triggering sync from your repository. When you run phrase pull or trigger the export to your repository it will group keys into files based on their tags.