Array not displaying in twig template Custom twig template is just this:

&lt;ul id="rows"&gt;
  {% for product in products %}
    &lt;li&gt;{{ product.title }} &lt;a href="{{ product.image }}"&gt;Image&lt;/a&gt; {{ product.description }}&lt;/li&gt;
  {% endfor %}
&lt;/ul&gt;


My custom module sends an array of products, which are something like this

array(1) { [0]=&gt; array(3) { ["title"]=&gt; string(9) "Product 3" ["image"]=&gt; string(56) "/sites/default/files/2019-11/128px-Small_Storage_Box.png" ["description"]=&gt; string(22) "Description 3" } }


And I am sending it from a controller like this:

return array(
  '#title' =&gt; t('Return products list'),
  '#products' =&gt; $products,
  '#theme' =&gt; 'return-products',
);


In my .module file I've defined hook as:

&lt;?php
function return_products_theme($existing, $type, $theme, $path) {
  return array(
    'products' =&gt; [
      'variables' =&gt; [],
    ]);
}


I know data is there in an array, it just doesn't go inside twig template. Even if I type some Test it won't be shown.
Several things are wrong here.

Your hook_theme must return:

return [
  'return_products' =&gt; [
    'variables' =&gt; [
      'products' =&gt; NULL,
    ]
  ]
];


Now you have a template called return_products with a variable called products.

In your controller you must then use '#theme' =&gt; 'return_products', instead of '#theme' =&gt; 'return-products',.

Then create a template in mymodule/templates/return-products.html.twig.

Notice how your theme name must be with _(underscores) when referred to in PHP, but the file name must be with -(dashes).