← All Talks
Presentation Development and Protocol

Blousques: Case Study on the Challenges in Translating Bluesky's UI

Stanislas Signoud (Signez) · @signez.fr
Sunday, March 29, 2026
11:00 AM – 11:30 AM PT
Room 2301
Available in-person & via livestream — Stream 3 (Room 2301)

Translating Bluesky's user interface into French was the easy part. Making it feel ‘native’ to users is something else entirely! I18n is common in software, yet Bluesky has specific challenges: should we translate it using gender-neutral terms? How to translate names embedded on-protocol? How to translate features not yet released, as an external, voluntary contributor? Translating the UI is also a good way to spot what is really missing in the daily lives of non-English users of the platform.

Okay. Thank you everyone for being here. Hi everyone. Thanks for joining me today. My name is Stan. But call me Stan. I'm also called Signe on the internet. So it's pronounced like this. But of course, nobody besides language nerd know how to pronounce those letters. So you can simply remember see me hey and you correctly pronounce it. But call me Stan, it's easier and nobody cares. My internet handle or my AT Protocol uh nickname is Signee.fr, and I'm Senior everywhere else. And uh there are a lot of you know key facts about me, but honestly, everything that you will see on this slide doesn't matter because I'm French and this is the main thing that you will have to remember about me here.

And that is also why I won't do so many that much of eye contact because I will have to follow my notes because it's a very dense presentation. I will try to you know respect the timing. Um and also I have a weighted accent that you you you may have noticed that and I will be talking a lot about French from France, which is Fr F R for real for real. And that is uh that is key because I'm sorry for all the Quebecwa and also the Belgian and Switzerland guys and also all the people from Africa that speak French, a lot of people over there, and will not focus about that because I had to crunch it down to only 25, 30, 35 minutes.

So um let's go on. Um I'm here because I'm the main volunteer translators of Blue Skies UI in French. Uh everything on the website besides user-generated content, of course, is translated in French, and that's partly because of my volunteer job that I do early in the morning before taking my croissant. Um with uh yeah uh breakfast and my favorite boulanger, and that is not a joke. I actually do that. So maybe you are thinking right now that what I do is practically this. Um uh taking Bluesky source code, translating thing, and ta-da, uh Bluesky is available in French.

Surprise, that's not that simple. Um I encountered a lot of little problems, a bunch of anecdotes that can actually help you um design better products, I think, and uh simply if you are just curious about it, uh learn a little bit of you know um uh behind the curtain things about how to actually internationalize uh localize such a complex app. So here is our roadmap for today. Um as you can see I've uh used some examples of real case that I've uh faced um besides the joke of the the beginning. And each time we'll get back to this roadmap, you will learn something that will uh uh replace those cases.

So let's start with the first one. It's not poster poster, it's poster. The verb. So here is the UI of Bluesky with an equivalent of the example.com situation, a Jerry post. And as you may notice on the top of the screen, there is a header that says post, because what you just have seen is a post. Signage is not really it's sometimes redundant, but it's useful to know. Uh and let's say that this very funny post uh inspired me to write another funny post. So I boot up the I open up the post composer and look here on the top right corner.

A post button. Of course, in this context, you know that it's not some header, it's it's just just a button. And uh post is written here because we write infinitive form of verbs uh on top of buttons. Uh maybe it's imperative form, yeah. You say post. Yeah, make it obvious. Whatever. So to recap in English, US, you have those two posts, but that doesn't actually mean the same. They are broadly the same, but they are not the same. One is a verb, one is a noun. Let's say that I want to translate that in French. No, I think that you are coming to what I'm going to.

Um so I want to change this to poster, which is the French for to post. So I open up crowd in and uh I can see this, of course it's a very simplified version. And oh, there is post. So I will change it to post A. When I get back, oh perfect. Post A. But have you may have dust yourself? Here is poste, and that doesn't make any sense. So something is broken, and to explain why this is happening, I have to talk about international internationalization. By the way, did you ever notice that there were 18 characters?

That's why we write it like that everywhere. Actually, a lot of people don't know that, and it's a weird way of doing an acronym, but yeah. There are two main ways of organizing strings, translations. In a project, you can either decide on a reference language, a reference language, not surprisingly, most of the time it's English. And every word uh that is shown to the users is directly written in that reference language in the source code. And then internationalization libraries and check out if there are any translation for those words in the translation file and swap those.

But you have also another strategy that is the year article in that eDIT fire, you got it. And uh basically you treat all the words shown on the screen as external data that you reference using symbolic keys like those. The benefit of this approach is that those identifiers are clear for translators because we have context. And uh you can edit the the text shown to users even in your own language. So if you want to, you know, uh change uh what we also call microcopy, you know, the word that you use to for the users, even in English, you can do so without changing the source code, which is something you can then ask.

Um it's also cool because in a thinking way, English is just another language, it's not the reference language. So that's a cool way to do that. But Bluesky shows the former. And honestly, I do understand that because let's be honest, most English speaking developers um just want to iterate very quickly and they just slap uh the translation of the translation after the fact, and so yeah, this should shows the first strategy. And it's very common and honestly it works. So, and this is one of the two slides with code on it. Um we just slap the trends tag into that.

And like lives, uh, this trance tags matters a lot. Um it's a way for the international library to do its job and go fetch the actual translation for that string here, post. So now that you know a little bit more about internationalization, uh, how can we fix this problem? Well, actually it's quite simple. Uh and even if we have to do something on the source code, of course. Um, we just have to add context tags. Basically attaching some context to each of these strings. Uh the first one is basically you know uh standalone known, the second one an action verb.

And in the code, the second slide, uh we simple uh simply have to add context equal description because post is a description of the thing, not an action. As soon as we do that, the catal the localization catalog updates, and we have two separate entries, and I can simply translate the second one and not the first one. And tada, everything is translated correctly. Success. So the thing that I want you to remember for this first example is context is everything. Something that we know, but it's it's important to you know to to say again. Um and you have to be ready to hear uh the demands of your translators uh to add context tags if you use the first strategy.

If you use the second, normally you shouldn't have to do that because it's already in the identifier. And to their credit, the Bluesky team always accepted our pull request very quickly to add context times, uh context tags, so that's awesome, and I thank them for that. So context is everything. Let's get to um the next one, abonné with those weird points. And um you will understand why they are there, they're where they're weird dots. Uh but first let me tell you a story that starts with a GitHub issue. Um, this GitHub issue created by Fennerie Larsa is quite simple.

Make the French translation uh gender neutral. And as uh as I said, um the current French translation does not follow the current recommendation for non-sexist and more inclusive French forms. To explain what he's talking about, I have to explain a few things about French. So please bear with me while I will try to offer you some French 101 lesson. And now you understand why it may take a long time. This is a hat. In French, we would translate it as unchapeau. This is a tulip. In French, un tulip. Une tulipe. Yeah. Did you notice une tulip?

It's a feminine word. In French, everything is gendered, which are the gender for everything, and there is an aesthetics here, but honestly, nearly everything has a gender in French, even for brand new words. So some example of gendered things so you you understand the mess that it can become. This is a chair. It's feminine. Une chaise. It's masculine, unsiège. This is a shoe. It's feminine. This is a finger. It's masculine, it's a finger. But it got even weirder because here is Canada. It's masculine for some reason. But here is Poland. It's feminine for some reason. Strength is feminine.

La force. Love is masculine. An amour. Ooh lala. When we say when I say nearly everything, really I mean it. So gendering is not optional. This is a key thing that you have to remember. If you say un tulip inside a sentence, and you are not a beginner or a tourist, that means that we have not switched to in the quirks mode, uh, that uh we will do some extra mile or you know uh uh extra kilometer, as we say. Um, we will offer to correct you, uh, even verbally, because we will assume that you made an error or we didn't understand you.

It's like a checksum or CRC. So that's not the end of it. Here is a big hat, a grand chapeau. Here is a big tulip. Une grande tulip. In French we do an accord. This means that we do change the form of the adjectives that comes with the noun. By the way, I learned that it was called a co chord in English, but nobody says that, so we don't care. Um here are two tulips. Actually, we you do a chord in English, but only for the noun. Um, and we do it, of course, in French. Uh here is two big tulip tulips, so of course the grande tulip.

Both gender and number are used in the circle. And it also works with people. Um so we talked a lot about uh gender of stuff, but of course gender of people also affects the language. Here an old man, un vieil hom, two old men. Oh, did you notice you also do an accord with a weird thing, it's not not only about other languages. Um de vieux homme, two old women, deux vieille femme. Now that you uh have all that in mind, uh let's take a more complex example so you understand the problem that is coming. Um here is a detective.

In French, we can translate that to an inspector. And the gender is visible because it's an inspector, because if it was a female detective, it will be une spectrice, as you can see, une child, but also inspectress. And that means, oh by the way, we don't know the gender of the user. So maybe you can deduce the problem that we can have at some point. But actually it's not the actual problem that I'm talking about right now, but of course it happens also, it also happens. When you have two detectives, a duo of detectives, one male detective and a female detective.

Together we call them two detectives. Which gender should we use in French for this group? Well, you will have to use a masculine form, the inspector. I know. But here is a team with five detectives, and four of them are female detectives. How should you translate five detectives in that case? Masculine again. Cinq inspector. This comes from an old rule we learn even learn in school. Le masculin l'emporte, the masculine takes it all. As soon as there is one noun, subject or part of a group that is masculine, we should use the masculine group for the world group.

And let's be honest, this rule sucks. People try to reason about it, saying that in masculine uh in French, masculine is a neutral form, it's a cop out. Always gendering in masculine in the masculine form, sorry, the masculine form blocks some young women from projecting themselves to wall domains, can make them feel non-represented, and uh moreover, it's that's just unfair in a lot of ways. So at some point in the 21st century, some people got fed up with that and tried to change things by using something that they called écriture inclusive inclusive writing. Basically it's just voluntary using some word piece of sentences and tricks to make sure that we stop excluding women from the language.

So here are two main strategies that we can use to implement include to implement écriture inclusive, sorry, either write both masculine and feminine forms every time, in whatever order, by the way, or merge both forms into a sing a same word like this. And to do that, you use some point médian, which are basically interpucked, but nobody says that even in English, uh, which are basically dots that you place in the middle of the vertical height of the line. Of course we could use parentheses, but then you put 50% of the population inside parentheses, and so yeah, that's weird, so we tend not to do that.

Ecriture inclusive uh as a linguistic innovation was fringe at first, but uh as time goes by it became more and more common use, especially from companies and agencies, because it was easy and an efficient way to making clear that you wanted to the situation improving, showing that you cared about the subject of gender inclusivity. But then, after a few years, I'd say five, six years of widespread usage, some right wing people started to ask themselves, you know, this role a creature inclusive thing. Isn't this woke? I mean, they focused a lot about those point median form, they call it something ugly, weird, decadent or whatever, and basically created an equal sign between using the point médian and being woke.

Um it was bullshit, you know, but it's like that kind of stuff. It's not like this kind of stuff would stop them. It's perfect scalable goat for them. So of course they started coming to the Bluesky repository, complaining about using politically sided language. Um just because we followed a somewhat common new practice of caring about inclusivity. So from there, what should we do? Well, um actually I thought about that before they even complained. And um I strained myself to mainly use the long way of doing écriture inclusive by both uh writing the you know the fame the feminine and masculine uh um forms.

Um then if and only if we have very little room for the translated version, then at a last resort using point media uh short form, uh and it's what we did for abonné, by the way, the example, the the title example that I used. But we have some trick up our sleeves to make it better. And to be fair, I lie to you, I'm sorry. By omission, let's say. What if there are there were words that shared the same form in both gender? That's why I use detective as an example. A detective can also be translated in French as a detective, and a female female detective as in detective.

Perfect. Those words that can be written the same in both masculine and feminine form are called episode words. And uh they're awesome for us because they basically solve the problem in a very nice way. However, they don't always exist. They are not always synonyms that have this property of being epicen, including abonné, by the way, that's why I have to use that. So to recap, going forward when I face this kind of puzzle in my translation work, uh, my policy is to try to find an episode word, and if I can't find one, then to use the exponent version with both masculine and feminine form, and then and only when space is missing as a last resort, using the point median.

And here we have it. And by the way, and this as a conclusion for this part, here is what Dan Abramoff that uh at that time part of the Bluesky team posted before closing that pull request that wanted to revert uh the work that we did on gender neutral uh language. It was very validating to see part of the Bluesky team officially recognizing the work we did, the balance we try to find by not using the somewhat controversial uh to the far right, um, new forms uh where we could, and moreover the pragmatic approach we I try to follow.

So thank you again, Dan and the Bluesky team for our support. Builders, please support your translators if you are agreeing with the choices. Okay, um. Let's get to the fourth point. Um, and we have uh short time to go on. So um it's going way easier now. Uh but not easier, but quicker to come to to understand. So this traduit language d'origine, anglais. A very quick, only one side, um a short uh uh um French 102 session. Um I reassure you it's very very quick. Um, this is the cat. It's it's the cat, you would you would agree, I think.

Uh is beautiful, and in French we would say le chat. And this is the tree, it's such a beautiful tree, it's the tree. And we would say l'arbre, not le arbre. L'arbre. Uh because le arbre would sound weird, we get rid of the e and we replace it with a little apostrophe. E lesion is not optional. If you don't do it, we will get back to the same we'll crash in a way, and we'll ask you what did you just say because we will assume that something went wrong. It's like a checksum again. So when we get back to translating software, uh for example, if you have a message like new new message from uh Alexandre uh in English, it will be translated as nouveau message d'Alexandre in French and uh not nouveau message de Alexandre.

That wouldn't work. Um we are used to software not doing the elision stuff because um it's hard to do it properly. Uh there are some letters that only triggers the lesion in some cases, the H aspir if you know French, and uh there are a lot of uh hard-coded exceptions in the language too. Uh so yeah, uh we love exceptions in French. So because of that, um international internationalization library just don't care. And um uh there is no standard way of doing it uh like with pull over genders, so uh yeah, it's perceived as too hard and stuff done.

So what can we do? Well, uh if we I take this actual example from the Bluesky app to translate a string like translated from English, ideally we would write traduit depuis l'anglais, but we can't because it's hard to encode that in a translation uh system. So uh we can't do traduit depuis le anglais because it will sound like that, and uh we can't do traduit depuis anglais either. So we have to do workarounds like traduit original en anglais, literally translated originally in English. Or um because on doesn't have this elision stuff, so we don't care, it works.

Um actually I didn't use that one but an even clearer one because in that context it could be a little bit you know complex. So I use traduit language original anglais, translated source language English. Fun fact from this morning, it's an exclusive. Um I wanted to make sure that I quoted my translation correctly, and this morning I tried to find it and encoding. And uh no, there weren't any translation about that. So I took my phone, got my one of my English shit posts from uh day ago. Um it translates and yeah, in the meantime, Eric, the designer, one of the designer of uh Bluesky changed actually all the world design, and this string it doesn't exist anymore.

There is a a nice arrow that conveys the message even easier over there. So yeah, better. Sometimes you know, design can solve this kind of thing. But honestly, I prefer this anyway. So it's a good ending in my box. Uh sometimes there are no perfect selection, only walkaround. This is the key thing that I want you to remember. We try to do our best, but sometimes, yeah, you know, we can do what we can do. Um, my last point um is about uh following discover and for you, etc. As you may uh here is the UI in French, so I will dim out all the user-generated content.

So we can think you can see that nearly everything is translated in French. Nearly everything is translated in French. Not those. Why? Well, because feed names are not part of our language catalog. And you could say, oh, but feed names are user generated. Yeah, but you may have noticed that I said before, maybe not if I wasn't following my notes, um, perceived as user generated. Because users don't always perceive those words as provided by users, but part of the product. So it's weird that they are not translated. We can't translate those data ahead of time, and we could use some acts to find and replace the most popular one.

That's something that actually there is uh an open pull request from SurfDude 29 to do exactly that. But it's not a very fool to proof uh way of uh fixing this problem in my opinion. So how should we proceed? Well, I don't know. No, honestly, I don't know. Uh please, dear atproto nerds, uh, this is a mission. I give you your homework, please figure this out. Um we have to figure out a solution to that. Um actually we were able to do that with labels, moderation labels. I've just learned that from Travis from Cartridge uh that explained that to me uh yesterday.

But it wasn't done for uh feed name, it's so frustrating because they are the very prominent part of the UI for good reason, it's a very good feature. Uh and uh yeah, it's very frustrated that it's not translatable right now. So here we have it. Uh context is everything, support genders and translators, workarounds may be required, user content should be translatable as soon as they are not perceived as user content. Is that it? No, of course not, it's not the end of it. Translating stuff is only a small part of the equation. You shouldn't think about localization holistically.

That's um that because um as an integrated experience, um language and region specific stuff are everywhere. And uh again, we don't expect you to figure it out from day one uh or to figure it out by yourself. You can't know everything. But even I would say that every given uh will provide tremendous value to users around the world. Um we talked a lot about um what could also be translated in the previous uh panel, but just to recap, um terms and conditions are not translated right now for Bluesky. Uh community guidelines are not translated right now for Bluesky.

It's kind of weird in a way that we expect users to respect rules they can't even read. Uh training topics are not localized, and one key message that I want to give you is we don't care about the NFL. Stop trying to tell you to tell us about the NFL. We don't care. It's just weird thing. You don't even use football correctly. Weird. Um and also blog post and help pages are not translated right now. Um, you know, discover feed algorithms, um, Night Heaven did a great leaflet about that, um, are not localized, so you will uncontrol a lot of um content that is not on in your language, and you can uh there are some alloist uh systems that are in place, but nah, that's not very that's a hack, not a proper localization.

And of course, announcements right now, Bluesky do not do announcements in any other language that's Japanese and English, and that's it. That's weird. But we talk a little bit about that in the previous panel. And here we are, thank you for listening. Um to see my work in action, thanks. As a guy said at some point, please clap. Um, do see my work in action, you can just go to the settings and change the language to French. Uh, I also want to thank uh surf dude 29 because this guy uh simply is an informal uh translation manager for the whole uh Bluesky open source project.

He do it in its spare time, and that's awesome that he do that, and also thanks uh people Montis that helped me uh figure it out some stuff on those slides. And of course, a big shout out to all the other fellow translators. I hope that I didn't um you know uh say anything weird uh about your work too. And uh as Stanley Parallel said, um the end even ever the end is never the end about all Do you have any questions? Do we have time for questions? Oh the no times. Ah sorry. So yeah. And feel free to follow me to know more about that.

Thanks. So much, Stan.