
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
@dialpad/i18n-services
Advanced tools
@dialpad/i18n-services contains all the tooling needed to manage the resources
for our i18n packages, i.e.
@dialpad/i18n-vue2 for legacy apps and
@dialpad/i18n for modern apps. this includes:
en-US.There are essentially two main concepts behind the scenes:
The BaseLocaleManager having the common logic that oversees internationalization (i18n) in a Vue2.js and a Vue3.js application using the Fluent localization framework. Its responsibilities include:
.ftl data, which
maps keys to text for each locale.$t, $ta) to
Vue templates, enabling localized content within the application.The second key concept is the BundleSource interface, which abstracts the
loading and management of localization resources. This interface has two primary
implementations: RawBundleSource and HTTPBundleSource, each designed for
different use cases.
RawBundleSource: This implementation handles localization resources defined
within the application. It organizes these resources defined directly in the
application, and imported directly at runtime (for example, using
import(./[locale].ftl). This approach is ideal for applications with mostly
static content.
HTTPBundleSource: This implementation fetches localization resources
dynamically from a server. It caches these resources locally, allowing for
efficient access while still being flexible enough to load translations on
demand.
Disclaimer: Both implementations are provisional and may change as we
better understand our needs. Currently, RawBundleSource is the preferred
option for most applications.
While the dynamicResources method is used for asynchronously loading resources, the RawBundleSource class also provides a builtResources method for synchronous resource loading. This is useful when you have the localization resources available at compile time and prefer to import them directly without dealing with promises.
Instead of dynamically importing .ftl files, you can import them directly and
use the
builtResources
method to process the resources. Here's an example:
import { RawBundleSource } from '@dialpad/i18n-services';
// Import your .ftl files directly
import enUSResource from './locales/en-US.ftl';
import esResource from './locales/es.ftl';
// Create an array of BuiltResource objects
const builtResourcesArray: BuiltResource[] = [
['en-US', 'namespace', enUSResource],
['es', 'namespace', esResource],
// ... add other locales and namespaces as needed
];
// Convert BuiltResource objects to Resource objects using builtResources
const resources: Resource[] =
RawBundleSource.builtResources(builtResourcesArray);
// Now, resources can be used to instantiate RawBundleSource or for any other purpose
const bundleSource = new RawBundleSource({ resources });
If you're looking for the 'Dialpadistan' translator, please skip to this section.
pnpm add @dialpad/i18n-services
You can find the needed configuration for using $t and $ta functions in your
application in the i18n for vue2 and
i18n for vue3 documentation. In both cases the needed
configuration should be the same.
addSourcesaddSourcesThe addSources method allows you to add multiple translation resources to the
LocaleManager at runtime. Once all resources are loaded, it triggers the
ready promise indicating that the locale manager is fully initialized and
ready to handle localization requests.
sources: An array of BuiltResource items where each item contains:
locale: The locale code for the translation resource.namespace: The namespace associated with the resource.source: The actual source string or a promise that resolves to the source
string.// Assuming you have a LocaleManager instance
const manager = new LocaleManager(...);
// Define your resources
const resourcesToAdd: BuiltResource[] = [
// Array of [locale, namespace, source] tuples
['en-US', 'namespace1', sourceStringOrPromise],
['es-ES', 'namespace1', anotherSourceStringOrPromise],
// Add more resources as needed
];
// Add the resources to the LocaleManager
manager.addSources(resourcesToAdd);
The API for our i18n tools is the same either for the vue3 or vue2 supported versions. You can find the more details about how to use the tool in the i18n for vue2 and i18n for vue3 documentation.
This feature uses the @fluent/syntax parser and a set of regex and grammar
rules to convert an en-US.ftl file into an dp-DP.ftl inside the same
directory. The "dialpadistani" language is just the original language
transformed character-per-character to non-latin characters which is useful to
test the proper render of different fonts.
For example:
# src/localization/en-US.ftl
MESSAGE_INPUT_LABEL = New message input
FEED_NEW_SEPARATOR = Beginning of unread items
Will translate to:
# src/localization/dp-DP.ftl
MESSAGE_INPUT_LABEL = Ŋάŵ ɱάššëğά īŋþøâ€
FEED_NEW_SEPARATOR = Sάğīŋŋīŋğ ůƒ øŋřάëḍ ī†άɱš
To execute a Dialpadistan translation you should run the following script pointing to your Fluent English file: (Note: it can either be a relative path or an absolute path)
pnpm pnpm --filter=@dialpad/i18n-services run translate:dialpadistan /your/english/fluent/file/en-US.ftl
When succeeding translating, you will notice a message on your terminal stating the folder where the output file will be placed. This folder is the same as your English Fluent file.
e.g. in this case you will see
File transformed and saved as /your/english/fluent/file/dp-DP.ftl.
This translator includes a post-commit that automatically translates english
files to dialpadistani. This hook checks the commit for changed en-US.ftl
files and will only run the translator against those files that had changes in
the commit.
If this script finally makes any change to dp-DP.ftl files, it will
automatically commit those changes with the message:
chore(auto-generated): translate en-US.ftl files to dialpadistani
There is one specific scenario where this translator is failing, and we don't
consider it to be harmful. This is because of a bug on @fluent/syntax parser.
And this is when having a comment right in the middle between an equal sign and a value, and that comment has at least one placeholder, whatever's after the text of the first placeholder will be translated (and if the comment it's multi-lined every comment line will be squashed and inlined after that placeholder as well)
e.g.
MY_KEY =
# My awesome comment
# And here the {$placeholder} is present
.aria-label = { $name } ({ $muted ->
[true] Muted{" "}
*[other] {""}
})
will be translated to:
MY_KEY =
# My awesome comment
# And here the {$placeholder} os sintirp
.aria-label = { $name } ({ $muted ->
[true] Muted{" "}
*[other] {""}
})
This is because the way@fluent/syntax parser works at the current version. In
order to fix this it would require an amount of effort that is probably not
worth it. It will imply either to patch the parser behavior somehow or extra
usage of regex pre and post processing files, which will not only increase
complexity of the solution but also reduce the robustness of it. And given the
fact that is just a comment, we prefer not to solve it in-house and wait until
they fix or improve this behavior on upcoming versions.
But keep in mind that whenever adding comments, it should be before the whole KEY = VALUE and not in between.
Context screenshots are, as their name suggest, screenshots that provide context to recognize where each translation is used in each app.
Each screenshot should contain visual information of where the translation can be found in the app with enough context to be easily located. If other dev looks at the screenshot they should be able to locate it fairly easily in your app.
There should be one screenshot per each translation key on each .ftl file. You
can reuse the same screenshot for multiple keys, but each file will correspond
to one key, so you must make one copy for each translation key. The screenshot
filename will be {translationKeyHere}.png. We only support .png images for
now.
There is a PR check which will fail if any translation key is missing its corresponding screenshot. There is an exception list for paths that should be ignored by this check. Avoid using it unless it's completely necessary. If you strictly need to use it, remember to mention in your commit message why you are using it.
These screenshots will be located in a directory called context-screenshots
sibling to each .ftl file in your project. If you have an .ftl file, it
should have a sibling screenshots directory. Each screenshot has a file size
limit of 20MB.
The screenshots are uploaded to smartling along with the CSV/FTL files through a github action when a PR to main is merged.
The following GitHub workflows handle various aspects of the translation process:
Name: Pull translations from third party translation service
Purpose: This workflow synchronizes translations by pulling them from a third-party translation service (Smartling) and automatically creates a pull request if there are any changes.
Triggers:
main branch0 0 * * *)Configuration:
pull-translations.yml workflow from dialpad/wcf-sdk@v0.6.0Name: Manual Force Pull Translations
Purpose: This workflow allows for manual forced pulls of translations from the translation service, with configurable options.
Triggers:
Input Parameters:
USE_FTL_FLOW: Option to use FTL flow (boolean, default: true)SKIP_UNAVAILABLE_LOCALES: Option to skip unavailable locales without failing
(boolean, default: true)WORKING_DIRECTORY: Specifies the working directory (string, default: ".")NODE_VERSION_FILE: Path to the Node version file (string, optional)Configuration:
force-pull-translations.yml workflow from dialpad/wcf-sdk@v0.6.0Name: Check translations screenshots
Purpose: This workflow verifies if the screenshots for translations are up-to-date with their respective FTL files.
Triggers:
main branchConfiguration:
screenshots-translations.yml workflow from dialpad/wcf-sdk@v0.6.0Name: Push en-US.ftl to third party translation service
Purpose: This workflow pushes the English (en-US.ftl) source files to the third-party translation service (Smartling) for translation.
Triggers:
main branchConfiguration:
push-translations.yml workflow from dialpad/wcf-sdk@v0.6.0All workflows use Smartling as the translation service and require proper API
credentials (SMARTLING_API_USER and SMARTLING_API_SECRET) stored as GitHub
secrets.
FAQs
i18n common services and functionality
We found that @dialpad/i18n-services demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.