Getting Started
The majority of Rosey configuration happens in your static HTML, which is read and transformed by Rosey. In most places, configuration values are in the form of data-rosey* attributes placed on your elements.
#Tagging your first layout
For this guide we’ll work through a single example: translating the page title on the homepage of an Eleventy site. The concepts apply to any static site generator, so adjust the files you’re editing to match your workflow.
Our simple site has a single index page, which is configured to use a home layout. In our home layout, we’ll tag each instance of our title with a data-rosey attribute.
--
# _includes/layouts/home.liquid
--
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title data-rosey="title">{{ title }}</title>
</head>
<body>
<h1 data-rosey="title">{{ title }}</h1>
<section>
{{ content }}
<section>
</body>
</html>
The data-rosey attribute expects to be passed a key for the given translation. In this case, both of these elements contain the same text, so we can share the title translation key.
After building our site to a static directory, our homepage file might look like the following:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title data-rosey="title">My Website</title>
</head>
<body>
<h1 data-rosey="title">My Website</h1>
<section>
<p>Hello World!</p>
<section>
</body>
</html>
With our built static site on hand, we can now start running Rosey. The easiest way to run Rosey is through the npx wrapper, which the following commands will use.
#Generating the source translation file
Rosey’s generate command is our starting point, which will generate our base translation file. For our simple Eleventy site, we should now have the following directory structure after running our site build:
.eleventy.js
package.json
_includes/
└─ _layouts/
└─ home.liquid
_site/
└─ index.html
index.liquid
With our built static files in the _site folder, we can run the generate command:
npx rosey generate --source _site
Rosey will read the static HTML and extract any elements that have been tagged for translation. We now see a new file in our project:
.eleventy.js
package.json
_includes/
└─ _layouts/
└─ home.liquid
_site/
└─ index.html
index.liquid
rosey/
├─ base.json
└─ base.urls.json
This base.json file contains all text that needs to be translated. For the layout we tagged above, this will look like the following:
{
"version": 2,
"keys": {
"title": {
"original": "My Website",
"pages": {
"index.html": 1
},
"total": 1
}
}
}
For now, all we need to look at is the original value of our key. The other values are useful to provide better context for integrations, but otherwise aren’t important.
#Creating locale files
The next step from Rosey’s point of view is building a multilingual website, but in order to do so we need translated content. Rosey expects translated content to exist in the rosey/locales folder, so to create a localized version of your site in Korean a file should be created at rosey/locales/ko-kr.json:
.eleventy.js
package.json
_includes/
└─ _layouts/
└─ home.liquid
_site/
└─ index.html
index.liquid
rosey/
├─ locales/
│ └─ ko-kr.json
└─ base.json
This file should contain translation keys, each containing the original and translated text. For our base.json above, our ko-kr.json locale file will look like:
{
"title": {
"original": "My Website",
"value": "나의 웹 사이트"
}
}
The original text here will be used to detect translations that are out of date, and the value text will be used to build our multilingual site.
Creating these locale files is currently out of Rosey’s scope. For smaller use-cases, these files can be written by hand. For larger use-cases, some kind of middleware is required that creates these rosey/locales/*.json programmatically.
In some cases this middleware could simply upload the strings from your base.json to a translation API (e.g. Smartling), and create rosey/locales/*.json files with the translated response. In other cases, a piece of middleware could generate translation files that are editable by non-technical translators using a CMS like CloudCannon, which could then be generated into the rosey/locales/*.json files needed by Rosey.
The Rosey CloudCannon Connector is a piece of middleware that can both be integrated with Smartling to provide automatic AI-powered machine translations, and/or to generate the files needed for non-technical editors to enter translations using a GUI like CloudCannon’s CMS. You can install the rosey-cloudcannon-connector as an NPM package, or use it as inspiration for writing your own custom middleware.
#Building the multilingual site
For our running example, we’ll assume we have created translated locale files for no and ko-kr:
.eleventy.js
package.json
_includes/
└─ _layouts/
└─ home.liquid
_site/
└─ index.html
index.liquid
rosey/
├─ locales/
│ ├─ ko-kr.json
│ └─ no.json
└─ base.json
With these newly-created files in place, let’s run the build subcommand:
npx rosey build --source _site
We will now see a new translated copy of our static site alongside our original built directory:
.eleventy.js
package.json
_includes/
└─ _layouts/
└─ home.liquid
_site/
└─ index.html
_site_translated/
├─ en/
│ └─ index.html
├─ ko-kr/
│ └─ index.html
├─ no/
│ └─ index.html
└─ index.html
index.liquid
rosey/
├─ locales/
│ ├─ ko-kr.json
│ └─ no.json
└─ base.json
At a glance we can see that Rosey has created a subdirectory for each of our languages. Peeking inside _site_translated/ko-kr/index.html:
<!doctype html>
<html lang="ko-kr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title data-rosey="title">나의 웹 사이트</title>
<meta content="ko-kr" http-equiv="content-language">
<link href="/no/" hreflang="no" rel="alternate">
<link href="/en/" hreflang="en" rel="alternate">
</head>
<body>
<h1 data-rosey="title">나의 웹 사이트</h1>
<section>
<p>Hello World!</p>
<section>
</body>
</html>
We can see that Rosey has translated the content we tagged, and has also added some SEO metadata for the current and alternate languages.
The main entry point of the website (_site_translated/index.html) has been replaced by a smart redirection page that takes a viewer to the language that best fits their web browser language preferences.
This new static directory is now ready to be deployed as a fully static multilingual website 🎉