Zach’s ugly mug (his face) Zach Leatherman

Building a multi-language Taylor Swift fan site (10 Minute Version) (Zach's Version)

December 22, 2023 Watch in 10 minutes
Watch on YouTube: 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.


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.

< Newer
In Case You Missed It: 2023
Older >
Netlify’s Disingenuous Survey-based Attack on Next.js (and Eleventy, too)

Zach Leatherman IndieWeb Avatar for a builder for the web at IndieWeb Avatar for He is the creator and maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 77 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »


Mike NeumegenCory :prami_pride_demi:Ricky de LaveagaSami MäättäMike-麥-Mai-v1.618 ????David LargeJeff Sikes


Liam BigelowMike NeumegenBoris MannCory :prami_pride_demi:Ricky de LaveagaJBDoug Parker ????️katherineLucas CantorAshur CabreracapjamesgDoomyTheFroomyMike-麥-Mai-v1.618 ????Elly Loel ✨????ColinautMatt SteinFernando MateusSanalJeff SikesNeblib
  1. Jens Oliver Meiert

    Jens Oliver Meiert

    @zachleat, I didn’t know Eleventy is a Swiftie

  2. Matt Stein

    Matt Stein

    @zachleat It’s nice to see a common use case get the attention it deserves.

  3. Philip


    @zachleat @cloudcannon @eleventy The title, I see what you did there.

  4. Curtis Wilcox

    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

  5. Curtis Wilcox

    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>`

Shamelessly plug your related post

These are webmentions via the IndieWeb and

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)