Plz point me if this is a duplicate thread.
If it's a duplicate depends on the context. The other thread is about websites specifically, but your topic is more general, so I would not say it is a duplicate.
As for Web Content, I use SHPS which includes a language module. All strings are entered into a database, ordered by a group and key. As an additional field, a FK to the language is stored. Translation is more or less just loading all English strings, copying them, changing the FK to the target language and translating the string. Inside the template, I can fetch the string in the correct language by calling a method with the group and key. SHPS deducts the correct language to use from the HTTP headers. If no language matches, the default language (I usually use English) is used. Of course, a certain language can be enforced, too :)
The following screenshot is a sample of a language entry in SHPS v4.3 with FK-field values pulled into the view:
SELECT
`langID`,
`language`.`name` AS langName,
`group` AS groupID,
stringgroup.name AS groupName,
`key`,
`value`
FROM
`string`,
stringgroup,
`language`
WHERE
`key` = 'status' AND
`string`.`group` = stringgroup.ID AND
`langID` = `language`.`ID`

// inside template
const d = require('promise-defer')();
lang.getString('form', 'status').then(str => {
d.resolve(`<span class="o-form__item">${str}</span>`);
}, d.reject);
d.promise;
For JS-generated content in the client, I can send over all strings inside a group to the client, so I bundle everything the client needs and the client can cache it and use it from localStorage. I usually do the same for templates: bundle all strings and retrive the bundle to use in the template, which makes the above boilerplate a lot less relevant.
When programming a desktop or mobile application, I usually take a similar route and store all strings in a resource file which I can parse and fill the corresponsing elements. On element creation, my code (custom lib) looks for a matching entry according to the element name. I name my components accoring to BEM notation, so it usually works out pretty well.
en,menu__btn-open,Open
de,menu__btn-open,Öffnen
Since the above syntax is very similar to CSV, I could even use Excel for simple programs, but I made a specialized program, which can handle commata inside the string and has additional translation functionalities.
Alternatively, INI or rather TOML work nicely, too.
As for my computer game, I still haven't built an internationalization system, yet, but I will probably port the SHPS module to Rust, since I plan on using an inline-DB like SQLite for different things either way.