diff --git a/app/models/communication/block.rb b/app/models/communication/block.rb
index 49768fb21121586bbb22893d96cbea065f83dad3..327082ab82b322f1aee761673bcb6d0be02d47e2 100644
--- a/app/models/communication/block.rb
+++ b/app/models/communication/block.rb
@@ -136,11 +136,12 @@ class Communication::Block < ApplicationRecord
     block
   end
 
-  def translate!(about_translation)
+  def translate!(about_translation, heading_id = nil)
     translation = self.dup
     translation.about = about_translation
     translation.template.translate!
     translation.data = translation.template.data
+    translation.heading_id = heading_id
     translation.save
   end
 
@@ -171,7 +172,7 @@ class Communication::Block < ApplicationRecord
 
   def set_heading_from_about
     # IMPROVEMENT: Ne gère que le 1er niveau actuellement
-    self.heading = about.headings.root.ordered.last
+    self.heading ||= about.headings.root.ordered.last
   end
 
   # FIXME @sebou
diff --git a/app/models/communication/block/heading.rb b/app/models/communication/block/heading.rb
index 8de82dadbd6067714a4b6ab3ec77f040773f5ba8..186320adca87be8c2484a44c3a19b37882498614 100644
--- a/app/models/communication/block/heading.rb
+++ b/app/models/communication/block/heading.rb
@@ -54,6 +54,21 @@ class Communication::Block::Heading < ApplicationRecord
     [about]
   end
 
+  def translate!(about_translation, parent_id = nil)
+    translation = self.dup
+    translation.about = about_translation
+    translation.parent_id = parent_id
+    translation.save
+    # then translate blocks
+    blocks.ordered.each do |block|
+      block.translate!(about_translation, translation.id)
+    end
+    # and then children
+    children.ordered.each do |child|
+      child.translate!(about_translation, translation.id)
+    end
+  end
+
   def to_s
     "#{title}"
   end
diff --git a/app/models/concerns/with_translations.rb b/app/models/concerns/with_translations.rb
index 761aa5a40526e3de3dce3fd9b50b3bc61cd3b340..f99868e9c6747f523ba64b2df3ff2b5a19cbff00 100644
--- a/app/models/concerns/with_translations.rb
+++ b/app/models/concerns/with_translations.rb
@@ -67,8 +67,8 @@ module WithTranslations
     # Handle featured image if object has one
     translate_attachment(translation, :featured_image) if respond_to?(:featured_image) && featured_image.attached?
     translation.save
-    # Handle blocks if object has any
-    translate_blocks!(translation) if respond_to?(:blocks)
+    # Handle headings & blocks if object has any
+    translate_contents!(translation) if respond_to?(:contents)
     translate_additional_data!(translation)
 
     translation
@@ -81,10 +81,14 @@ module WithTranslations
     parent.find_or_translate!(language)
   end
 
-  def translate_blocks!(translation)
-    blocks.ordered.each do |block|
+  def translate_contents!(translation)
+    blocks.without_heading.ordered.each do |block|
       block.translate!(translation)
     end
+
+    headings.root.ordered.each do |heading|
+      heading.translate!(translation)
+    end
   end
 
   # Utility method to duplicate attachments