In the last days I tried to migrate a multilingual CSV file to Drupal 8 without success, so finally I decided to use a Batch Process to accomplish the task.

At this moment I have the batch process working, but at this point I need to create my nodes and create the translation. So, how to create a multilingual node programmatically?

3 Answers 3


Fortunately I found a post named Create and translate a multilingual nodes programmatically.

And here is the code with some comments:

use Drupal\node\Entity\Node;

$node = Node::create([
  // The node entity bundle in this case article.
  'type' => 'article',
  //The base language
  'langcode' => 'en',
  'created' => \Drupal::time()->getRequestTime(),
  'changed' => \Drupal::time()->getRequestTime(),
  // The user ID.
  'uid' => 1,
  'title' => 'My test!',
  //If you have another field lets says field_day you can do this:
  //'field_day' => 'value',
  'body' => [
    'summary' => '',
    'value' => '<p>The body of my node.</p>',
    'format' => 'full_html',
//Saving the node
//This line is not necessary
\Drupal::service('path.alias_storage')->save("/node/" . $node->id(), "/my/path", "en");

//Creating the translation Spanish in this case
$node_es = $node->addTranslation('es');
$node_es->title = 'Mi prueba!';
$node_es->body->value = '<p>El cuerpo de mi nodo.</p>';
$node_es->body->format = 'full_html';
//Saving the node
//This line is not necessary
\Drupal::service('path.alias_storage')->save("/node/" . $node->id(), "/mi/ruta", "es");
  • 1
    I get the following error : InvalidArgumentException : Invalid translation language (en) specified. dans Drupal\Core\Entity\ContentEntityBase->addTranslation() (ligne 863 de /.../Core/Entity/ContentEntityBase.php). Jan 16, 2018 at 10:51
  • @Pauloscorps – You have to ensure the en language exists or maybe ensure the config that adds the en language got imported successfully before running Adrian's code.
    – leymannx
    Nov 7, 2018 at 12:36

I was racking my brain over this problem in Drupal 8. Here's how I finally got it done, This code copies title, body, all fields, and the pathauto setting. I'm sure there's room for improvement here as some meta fields probably need to get processed too. But this should get you started!

// This assumes you have a $node variable that contains the node translation you're starting with
$node_trans = $node->addTranslation('en-au'); // sample using Australian English
$node_trans_fields = $node->getTranslatableFields();
foreach ($node_trans_fields as $name => $field) {
  if (substr($name, 0, 6) == 'field_' || in_array($name, ['body', 'path', 'title'])) {
    $node_trans->set($name, $field->getValue());
try {
catch (\Exception $error) {
  $add_status .= 'ERROR saving ';

The last part of Adrian's answer didn't work for me.

For the translation part, use:

$node->addTranslation('es', ['title' => "Translate title"])->save();
  • Hi Tib, is weird, I copy the code from a working example that I have in a project. Jan 29, 2018 at 15:48
  • Hi, I'm on Drupal 8.4.2 maybe they changed something in the core. I don't remember the exact error but it was about the title field.
    – Tib
    Jan 29, 2018 at 16:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.