Seamless Drupal 7 multilingual site
Drupal 7 introduced new features that make multilingual sites much easier to handle. But Drupal itself is not trivial and you might get lost when you need to have your Drupal site divided into several languages. In this tutorial I will try as much as possible to make a step by step process and give some explanations and insights on how each aspect of multilingual sites work so that you can choose what are the best options for you. At the end you should have a Drupal multilingual site up and running without a glitch.
We will go through:
1 - The core features of Drupal 7 for multilingual sites.
-Detection and selection.
2 - The additional modules for translations in Drupal 7.
-Translation Management Tool (updated 11/2012)
3 – Fine tuning.
-Machine translations on the fly
1 - Core features
The core options for multilingual sites are Content translation and Locale. With these two options enabled you already have a multilingual site running.
To add a new language go to .../admin/config/regional/language and click on Add language. You can also decide what will be the default language, what is the path prefix (ex: www.example.com/fr for french) or the language domain (ex: fr.example.com for french).
With path prefix you will have one site with several languages, with language domain you will have several sites, one for each language. If your goal is to have the same content translated into several languages I would advise choosing path prefix but, if each language has a different content, a different administrator and different users then language domain might be the best option. Think well before choosing because it would be painful to change this once the site is online (it would break links to your site...).
If you want your visitors to go first to the default language and choose their preferred language from there, leave the path prefix or language domain empty for the default language. If you find more convenient to try to guess the user language, then add a path prefix or language domain to all languages, including the default one.
Some people seem to like mixing languages, having “Language neutral” nodes or displaying the original node if a translation is not available. I would strongly advise against mixing languages in a public site. If you do so, your site will be indexed by search engines with a given content and keywords. While your node is not translated you will be displaying duplicate content and once you translate it, some users will be directed to a page that is not in their language. (Note: see comment from Kristen below about i18n_redirect avoiding duplicate content).
Detection and selection
Drupal offers many ways to deal with user preferred language. You can use one method alone or several methods with a priority order (if one method fails then the next one will be applied). This option is under .../admin/config/regional/language/configure. Here is how each method works:
URL (prefix or domain) is probably the best solution for most sites. Be aware that you might have a small problem with path prefix but it has an easy solution. The problem is that there might be inconsistencies between the site content and the site interface. If you have, for example, an “About” page translated into spanish “Sobre” you can access the page www.example.com/en/about (the content and the interface are in English), or the page www.example.com/en/sobre (the content is in Spanish but the interface is in English because of the prefix), or www.example.com/es/about (...you got the idea). When Search engines crawl your site they will mix up all languages and you will loose visitors. To solve this you must install the module Global Redirect in order to make interface and content consistent. We will talk about Global Redirect module later on.
Browser can be very nice but it should not be the first detection method because user wouldn't be able to switch languages manually (they would have to change their browser's preference). When changing languages manually only the content will be displayed in the user selected language while the interface will be in the browser's language. Manual language selection wouldn't work at all if Global Redirect is enabled. I use the browser detection method only if all languages have a prefix and URL is selected as the first detection method. This means that users that type in a URL path with the language will be redirected to that language (www.example.com/it = italian version of the site) but if someone in Italy type only www.example.com he/she will be redirected to italian if his/her browser is italian, or to german if his/her browser is german and so on. (Note: see comment from Reinhard about issues with browser detection and cache)
I found that URL as first method and Browser as second method with prefixes to all languages (including default) is the best detection and selection method I could choose.
Session will append a session variable to your URL (www.example.com?language=es). It is not such a good idea because it prevents the pages from being cached (the site will be slower) and session can be a a problem because it will serve different content for a same URL. Google can handle session information although you might have to explain it in your Google Webmaster Tools, but overall it's not as straight forward as URL path or prefix. If you use URL and Session you will see that sometimes the session will not force a URL change so the language negotiation will be very inconsistent. I do not recommend using both URL and Session. There is a thread in Drupal.org against the use of sessions.
User preferred language is a bad idea because this means that users will not be able to switch languages easily and temporarily when they are signed in. Once the user is signed in, he/she will have to change languages in his/her profile instead of just using the standard default language switcher. This might be counter intuitive and annoying for bilingual users.
Drupal core also offers a way to translate your site interface and import translations from localize.drupal.org. This is under /admin/config/regional/translate. Although this works fine there are some additional modules that can improve dramatically the core functionalities.