Correctly setting the selection and detection of the user’s language
If someone visits your Drupal website you want to show your website in the user’s preferred language. In order to do this you need to detect this preference. You can configure this under Configuration > Regional and language > Languages > Detection and selection.
How you configure this is mostly up to the site's requirements. In all the projects I’ve worked on, the language was detected either by path or domain name. The language preference can be determined by the domain name the user visits showing only nodes in the language corresponding with the domain extensions (.com shows English content and .nl shows Dutch content). Another way is to use the path, where the domain name stays the same but /en/ or /nl/ is inserted into the URL. Optionally you can enable the language switcher so users can switch between languages changing either the domain name or the path.
In order to configure your Drupal website this way only enable URL as a Detection method. Note that Selected Language is enabled by default and can’t be turned off, which is fine. Also drag the URL detection method to the top of the list.
If your Drupal website is mostly served to logged in users it might be better to use User as the detection method so users can set their language in their user profile.
How to configure multilingual Views and remove duplicates
When you’ve created a view with nodes you only want to show the ones which are available in the language the user prefers. For example if a user navigates to the English blog overview page it would make sense to only show blog nodes which are written in English. And if a user goes to the Dutch version of the same page only blogs in Dutch should be visible.
The first thing you need to do is filter the view on the language the user is currently viewing. You do this by adding a Filter Criteria to your view. Select Content: Translation language and check Interface text language selected for page below language. This will ensure only nodes that are available in the language the user has selected will be shown.
You might notice some duplicates popping up now. Especially when a view has a relationship to another entity such as Paragraphs. In some cases setting the Query Settings to Distinct removes the duplicates. In my case it didn’t help, but I have since learned that setting the Rendering Language to Interface text language selected for page does help getting rid of duplicates.
Optimizing the Language selector
If you want users to switch to another language on every page you can place the Language switcher block via Structure > Block Layout. You can place this block anywhere you want, but as high up on the page as possible is common.
By default the language selector will show all the available languages written out like English and Dutch. This takes up a lot of space. It might be better to only show the language codes such as EN and NL. To achieve this you need to install the Language Switcher Extended module. Once installed head over to Configuration > Regional and language > Languages. Here you will find a new tab called Language Switcher Extended. Under this tab you have to check Show language code in order to display the language codes in the language switcher.
How to disable a language for untranslated content
In the same configuration overview I also like to set Untranslated Handler to Display the language without a link. Now, when someone visits an untranslated page on your website the language switcher will be shown, but the visitor cannot click on the language when there is no translation available.
Trying to get your multilingual Drupal website to play nice with Paragraphs can be tricky. If not set correctly, translating a node with paragraphs can override the original, which could result in content being lost. In order to configure the translation of your Paragraphs navigate to Configuration > Regional and language > Content language and translation. Under Custom language settings enable Paragraphs. Now disable all the fields that are referencing paragraphs. They are easily recognizable because they are marked with (* unsupported). Scrolling down you will see the Paragraph label and below all the paragraph types you’ve created. You can enable the paragraphs types you want to translate. Next enable the fields used in your paragraph types that should be available for translation.