Building a multi-language Taylor Swift fan site (10 Minute Version) (Zach's Version)
In the above video I walk through a Taylor Swift lyrics fansite I built to demonstrate a few internationalization features with Eleventy and CloudCannon.
Features
- Supports English and Spanish (any number of languages can be added)
- Custom redirects are not necessary! The HTML links just work.
- For-free inter-language page-aware language chooser (e.g. “Also available in…”)
- Translated header, footer, and banner (in a different repo via Site Mounting)
- For-free locale aware search from Pagefind
- Album art pulled from Spotify Open Graph images
- Deep links to various streaming services
- Built with Eleventy v3.0
- Using
node
front matter insongs.liquid
(to enable thebefore
pagination callback in JavaScript) - Using custom dual pagination with
before
chunking data between languages and songs.
- Using
- Using the seasonally appropriate
<snow-fall>
web component.
Searchable Transcript
All right, what's up everybody?Today, I want to talk to you aboutinternationalization or creating a website that can have multiple languagesand locales to really show off your content to a variety of global users.
And the term internationalization is often seen as i18n.And the secret behind the shortening of that term is there's 18 letters betweenthe I and the N, and they just get removed and replaced with an 18.So when you see someone talking about
i18n, they're really just talking about internationalization.Now there are a couple of ways to do this with CloudCannon today.You can go into your CloudCannon application, open up the Site Settings,and there's an i18n page in the build section of your site settings.
And you can click this little check box that will opt into the.internationalization workflow that CloudCannon has set up.And this is great. It will take your site.Create a couple of different languages
for it based on some data files that exist in yourrepository, and it will automatically redirectusers to the localized version of your site,depending on what language preference they have set in their web browser.
Another great tool in CloudCannon's arsenal is a tool called Rosey.Now, Rosey works very similarly.It's a little bit more powerful.It will take the output of your statically generated site, and again,
it will post process it to create internationalized versions of the site.But today, I'm going to show you a thirdoption that allows you to edit your internationalized stringsinside of the CloudCannon
application using Eleventy’s internationalization plugin.And we're going to do that throughthe lens of this Taylor Swift Super Fan website that I've built.This is a site that has two different languages on it.
It's got English and Spanish, and it's a lyrics website.So we've got a couple of songs here,but the internationalization piece of this is that we have, each website is generatedin English and Spanish using the Eleventy internationalization plugin.
So the internationalization plugingenerates links for all of the languages that you are specifying in your site.Every single page on your site will then have an internationalized link.So I can click through to a specific song
page, and that will also have a customized link to the Spanish version.One of the other things here is I builta tiny little web component to highlight when the user's browser languagepreference doesn't match the language of the page being shown to the user.
You can see the URLs are internationalized as well.If you look up in the URL bar, if we click over to the Spanish version,you can see that the URL changes to include the locale hereand then also the title of the song has
been changed to the Spanish version as well.Now, the other neat thing here is that allof the content on the page has been internationalized.So this content is actually coming through using CloudCannon site mounting feature.
So we have a banner that's set across all of my different demos.We have a drop-down here that shows links to all of the different demos that I'vebuilt so far using CloudCannon to show off the CloudCannon features,and all the content inside of this menu has been internationalized as well.
But that actually lives in a separate repository.And if you scroll down to the bottom,you also see the links and the footer have been internationalized as well.So the other thing you'll notice is that when you click around on the site,
if you are in the Spanish version, you will remain in the Spanish version.All the links are relative to the current language that you're browsing.And if you switch back, all the links will then be to English versions.So we're using the Eleventy
internationalization plugin to generate the HTML for this site.We have the English version of the websiteis available by default on the root of the URL structure.And `es` exists as a Spanish version.
And if you go into the CloudCannon app,the extra benefit that we get now is that we can edit these songs in CloudCannon.So technical and non-technical editors nowhave access to edit the lyrics of the site in different languages as well.
So we have our English version here,we have the title and the lyrics, and we also have the Spanish version here,which has a separate title and also separate Spanish lyrics.And so if we have a mistake here, we can come in and easily edit it.
We also have a URL section to link outto streamable versions of the song if you want to play the song.And the nice thing here is that we canextend this and add as many languages as we want, and all that lyric content
and song title content will be internationalized as well.All right, so let's go out to the sourcecode of this site, which links back to the demo that I've already shown.And we're using a package called Rosetta for string transformation.
And this is just a tiny general purpose internationalization library.We have a for-free locale aware search, which I think is just an incrediblefeature that you get for free with Pagefind.So we have Pagefind, if you noticed in the demonstration.
At the very bottom, you can search for a lyric.But I didn't have to do anything to makesure that the search is segmented across language.So I can search for farm here, and we'll get the index page,
which has the title here, and we'll also get the song page.But if I search for a Spanish lyric here,and I search for that, you'll notice that it only shows Spanishpages for the Spanish contextual search, which I think is a great feature.
I didn't have to do any extra configuration.It worked automatically offof the document `lang` attribute that was set on the element for the page.Now, one other thing here is we're using album art from Spotify.
We're actually pulling in Open Graphimages from Spotify's song pages so that we can show some nice album art here.And this is built with Eleventy 3.0,Which just released in our alpha versions this last week.
You can go to the Eleventy blog and read more about it.I'll link it up in the show notes as well.And maybe one more nice thing that you might have noticed is that on the demo,we have a nice little seasonally appropriate snow web component here.
This is called .And I'll link that up in the show notes as well.You can add that to your site.What's the source code look like?
It's a pretty standard Eleventy site.You can see some of the front-end dependencies are linked up here.You can see the back-end dependencies.We're using Eleventy 3.0, the Eleventy Image plugin
to fetch those Open Graph images from Spotify.We're using Pagefind for searchand Rosetta, as I mentioned, to internationalize our strings.Then in our configuration file,
this entire section is just an Eleventy Image piece.Then the magic gets into, we declare our languages here.These are all the languages that we want to use on our site.We set those languages as an array in our
global data, so we can use those in various places throughout our site's code.Then we also add the Eleventy internationalization plugin here.Now, this Eleventy.`beforeConfig` event is a pretty little known event, and this is to work around
synchronous versus asynchronous limitations in your Eleventy config file.This is only an Eleventy 3.0 feature, and this is to add asynchronousconfiguration code inside of a synchronous configuration callback.Now, again, we're setting the default language to English here in
Eleventy's Internationalization plugin, and this filter here is an i18n filter.This is a way to translate string contentinto the final output that goes into the site.You can see this is a shortcode that will fetch the album art for us as well.
It's using Eleventy's Open Graph API to fetch, again, the URL from Spotify.That's pretty much it for the configuration file.Next, we can look at the index page, which uses Eleventy's pagination featureto iterate over the languages that we set in our global data.
That's English and Spanish.And so we're generating two differentversions of our homepage, one for English and one for Spanish.So now let's look at this internationalization filter.
So you can see using Rosetta, you feed it a key that then is a lookupfor Rosetta's string library that it knows about.And I've wired this up to two JSON files in global data.You can see one is for English,
one is for Spanish, and we have just a bunch of internationalized strings here.Rosetta will look those up,but this is the key that we're feeding in in the template.So when you see songs here referenced
in our heading, that just calls out to the key in our data file "songs".So pretty straightforward,we're iterating here over our song pages that I'll go over next.All right, so the next thing I want to go
over is the CloudCannon data files that we're using.And those are markdown files that are in our songs folder.So you can see we have two different songs here and thenan Eleventy data file that then adds
a tag to every single song in this directory.So let's look at what one of those song data files looks like.We have our English version, which you can see the title and the lyrics here.If you scroll down, you'll see the Spanish
version here, title and lyrics, and then we have our URLs here at the bottom.That's the same for the other song aswell: English, Spanish, and URLs at the bottom.All right, so we have our markdown files.
Those are populated into a collection using this `tags` property here.We can now iterate over our songs in our songs.liquid template.And you can see that in the Pagination here as well.Importantly, in the before callback here,
this is a callback that Eleventy uses to allow folks to modify the Pagination data setbefore it's fed into Eleventy to generate pages.And I won't go over this code too much,but we're using it here to iterate over the songs: for each individual song
we want to output an English versionof the page and a Spanish version of the page.We're iterating over the songs, we're iterating over the languages.We're creating one page for each song and language combination.
And one last piece I want to go over here is we have our Eleventy layout file.This is an Eleventy internationalization plugin feature that gives you a list of linksfor the current page in all of the other languages.We're just iterating over that and showing those.
Let me show you what that looks like in the demo.That's this piece right here.It's also available in English and click through there, also available in Spanish.And if we added more languages to our
site, then those links would also be represented here.We could add Spanish, German, whatever you want to add.All right, so that's how you set up an internationalization site using Eleventywith CloudCannon while allowing your editing team to come in and edit
the internationalized strings as well right in the CloudCannon app.Hope you enjoyed it. If you have any more questions,you can post them in the comments below or just send us a message on social media.Thanks, and keep building for the web.
5 Comments
Jens Oliver Meiert
@zachleat, I didn’t know Eleventy is a Swiftie
Matt Stein
@zachleat It’s nice to see a common use case get the attention it deserves.
Philip
@zachleat @cloudcannon @eleventy The title, I see what you did there.
Curtis Wilcox
@zachleat @mikeneu Neat! I think it could benefit from a toggle to make it a static transcript, without the interactivity, so people can read it without the timecodes or button semantics while using a screen reader or any text-to-speech tech. The toggle control could do somethi… Truncated
Curtis Wilcox
@zachleat @mikeneu Also, the spans have `role="button"` but shouldn't. `<span data-offset="0" role="button"><button type="button">00:00</button>All right, what's up everybody?</span>`