typebot.io icon indicating copy to clipboard operation
typebot.io copied to clipboard

Add multi lang support for bots

Open os-mmasse opened this issue 1 year ago • 8 comments

It would be great to be able add a block "i18n" to create a translation map { default: "en", locales: [ { lang:"en", messages: { k1: "text1", k2: "text2" } }, { lang:"fr", messages: { k1: "FRtext1", k2: "FRtext2" } }, ] }

be able to declare currentLocale via script : i18n.setLocale(lang) be able to use it in all blocks like a variable {{ i18n(key) }} or maybe easier {{ i18n.key }} or {{ i18n[key] }}

os-mmasse avatar Mar 14 '23 11:03 os-mmasse

This kind of solution would make the bot flow unreadable, in my opinion, if you see {{i18n.key}} everywhere.

We need a deep multi-language feature for typebots where you can see the flow for different languages that you select with a dropdown.

Under the hood, yes, it would probably add a translation map to the typebot object.

baptisteArno avatar Mar 14 '23 11:03 baptisteArno

What about using an API like DeepL?

We have it working on Ghost and Discourse and gives really good outputs. We are unsing Weglot to correct the strings.

satonotdead avatar Apr 20 '23 02:04 satonotdead

I have started to play with adding multi-lang support and would like to discuss approaches.

Under Settings section of a Bot config, I think adding a toggle to enable Localization and select which languages are enabled. I have this working:

Screenshot 2024-07-24 at 9 23 19 PM Screenshot 2024-07-24 at 9 31 08 PM

Then within a Block, add a language selector menu that you can choose which language to add text content for, like this:

Screenshot 2024-07-24 at 9 22 12 PM

Ideally there is a LanguageProvider that provides a LanguageContext to components so they can react to the selected language, as well as control enabling and disabling languages.

I need help figuring out the right approach to storing the actual translations themselves. I feel that they should be stored as part of the Zod schema for the Blocks so that if the Bot is exported, the translations are included. Would be nice to be able to hook into a translation manager like Tolgee but I'm not sure how to do that.

`export interface Language { code: string name: string enabled: boolean default: boolean }

export type LanguageContextType = { languages: Language[] getDefaultLanguage: () => Language select: (code: string) => void getSelected: () => Language enable: (language: Language) => void disable: (language: Language) => void }

const LanguageContext = createContext<LanguageContextType | null>(null)

const LanguageProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const [languages, setLanguages] = useState<Language[]>([ { code: 'en', name: 'English', enabled: true, default: true }, { code: 'es', name: 'Spanish', enabled: true, default: false }, { code: 'fr', name: 'French', enabled: true, default: false }, { code: 'de', name: 'German', enabled: true, default: false }, { code: 'it', name: 'Italian', enabled: true, default: false }, { code: 'pt', name: 'Portuguese', enabled: true, default: false }, ]) `

`import { GlobeIcon } from '@/components/icons' import { Button, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react' import { LanguageContext, LanguageContextType } from './LanguageProvider' import React from 'react'

export const LanguageMenu = () => { const { select, getDefaultLanguage, languages } = React.useContext( LanguageContext ) as LanguageContextType

const handleMenuItemCLick = (code: string) => { select(code) }

return ( <Menu> <MenuButton as={Button} rightIcon={<GlobeIcon />} /> <MenuList> <MenuItem onClick={() => handleMenuItemCLick(getDefaultLanguage().code)} > {getDefaultLanguage().name} </MenuItem> {languages.map((lang) => { if (lang.code === getDefaultLanguage().code) return <></>

      return (
        <MenuItem
          key={lang.code}
          onClick={() => handleMenuItemCLick(lang.code)}
        >
          {lang.name}
        </MenuItem>
      )
    })}
  </MenuList>
</Menu>

) }`

Thoughts?

jwalsh-vori avatar Jul 25 '24 01:07 jwalsh-vori

I included a mockup of what I think the schema changes would look like in an JSON export of a bot configuration for a text bubble and a text input. What do you think? I need some help figuring out how to make this happen though :)

{ "id": "yprw6uqo90vmr822n59c5rv7", "title": "Say Hello", "graphCoordinates": { "x": -2875.63, "y": 199.19 }, "blocks": [ { "id": "fkmug80196oq9ddfuipg9qqw", "type": "text", "content": { "richText": [ { "type": "p", "children": [ { "bold": true, "text": [{"code": "en", "text": "hello"}, {"code": "fr", "text": "bonjour"}], "italic": true, "underline": true } ] } ] } }, { "id": "ph3mi6ry0w9cgo1r0sj8g6o6", "type": "text input", "options": { "labels": { "placeholder": [{"code": "en", "text":"Enter your reply..."}, {"code": "fr", "text":"Entrez votre réponse..."}]} } } ] }

jwalsh-vori avatar Jul 25 '24 13:07 jwalsh-vori

@baptisteArno any input here?

jwalsh-vori avatar Jul 25 '24 17:07 jwalsh-vori

This is a tough problem to solve that needs deep understanding of how the project works under the hood.

I appreciate the input but I think I can't really get help on that issue for now. I still need to explore the right solution.

Managing translation is a tough problem. This is why there are several softwares that exist (Tolgee, Crowdin, etc...). I can't imagine a fully fledge solution embedded in Typebot. But I am thinking about integrating it with these softwares. I will most likely start with Tolgee since we are using it for the translation of Typebot, the app and it is open-source.

baptisteArno avatar Jul 29 '24 08:07 baptisteArno

Wondering if to keep it simpler for now, the flow just stores the translations, which are manually entered by the flow designer, for each block and not worry about integration to a translation management solution? Solving for text bubbles and input placeholders would handle most of this. The other issue is the need to separate the flow logic & variables from the text display or just link them to the 'default' language.

Happy to help if I can

jwalsh-vori avatar Jul 29 '24 14:07 jwalsh-vori