Skip to main content

Blog Post

Deep Dive Into Translating Paragraphs

At Drupalcon, Jay Callicott and I presented “Multilingual in Drupal 8: A soup to nuts guide featuring and”, which featured a step-by-step guide to setting up a Drupal 8 site for content, interface and config translation. We ended up getting a lot of questions (I took this as a good sign), especially about how translation worked with the Paragraphs module. Paragraphs as a content structure has indeed gotten very popular. To maintain its place as a top multilingual CMS solution, Drupal translation must work well with Paragraphs. So does it?

Mediacurrent has launched a number of sites that involve paragraph translation, including and We recommend “full steam ahead” in terms of taking on multilingual projects in D8, including those with paragraphs. However, there are definitely some rough edges that may require workarounds.

Current paragraph translation model

Below is a diagram of how paragraph translation currently works.

Figure 1: Today’s Paragraph translation model
Today’s Paragraph translation model

This article goes on to explain more about this, including how to configure it.

The key thing to note is that the node only reference one set of paragraphs. These paragraphs are fully translatable though, so as long as you’re okay with your Spanish, English, etc versions containing the same translated paragraph entities, you’ll be fine. But is this a realistic expectation?

Problem: Untranslated paragraph bleed

In some projects, this constraint didn’t give us any trouble. However, we did encounter the following scenario:

  • Client was using TMS (e.g. Lingotek)
  • Client wanted to add a paragraph to a page with translations, and wrote the English version first.
  • They published the English version
  • It then showed up in all of the other translations, and the translated content wasn’t ready yet.

Figure 2: Untranslated paragraph bleed
Untranslated paragraph bleed

Solution: Paragraph-level language field

To fix this problem, we added an optional field to paragraphs to let editors pick a set of languages that each paragraph is allowed to display within. For example, to fix the problem as shown in Figure 2, we would set the value of our new “allowed languages” field to just “English,” at least until the Spanish translation was ready.

To add this new field, go to your paragraph type and add a new field. Pick “Language” as the type and set it to multivalue:

Figure 3: Custom language field configuration
Custom language field configuration

Then, go to your default translation (English in our case) for a node containing one of these paragraphs where you only want it to display in the English/default translation. Set the language value to “English.”

Figure 4: Setting paragraph allowed language
Figure 4: Setting paragraph allowed language

Now you need to write some custom code to implement the language restrictions. There are a lot of ways to do this. See below for an example that uses a theme preprocessor, assuming that you are attaching paragraphs to a node:

* Implements hook_preprocess_node().
function mymodule_preprocess_node(&$variables) {
 $content = $variables['content'];
 // Loop over your paragraph reference field render element.
 foreach (Element::children($content['field_paragraphs']) as $field_name) {
   $element = &$content['field_paragraphs'][$field_name];
   $paragraph = $element['#paragraph'];
   // Don't show the paragraph if it has specified a language set and the
   // current node's language is not in that set.
   if ($paragraph->hasField('field_language') && $paragraph->field_language->value && !in_array($paragraph->field_language->value, $variables['langcode'])) {
     $element['#access'] = FALSE;

Other methods include altering the node template and looping over the paragraph field content there, or you could even make a new field formatter for paragraphs. The idea is the same: loop over the paragraph output, load the paragraph object, compare its language preferences to the current node language and remove the paragraph from the display if necessary.

I hope that this helps anyone stuck on this issue!

Additional Resources
Top Drupal 8 Modules | Blog
Habitat for Humanity Launches New Website on Drupal 8 | Blog
Drupal 8: How To Reference A Views' Block Display From A Field | Blog

Dan Polant

Meet team member, Dan Polant

Dan is a skilled Drupal developer and problem solver who approaches coding as both an art and a science. He has been working with Drupal since 2010.   Dan became interested...

Learn more about Dan >