How to create custom node template file in Drupal 8 and 9 themes

Here we are going to discuss how we are going to over right node template from our custom theme.

Here we are going to customize content pages say a node of an article content.

Assuming you have a custom theme which extends a base theme.

In my case I have a bootstrap theme as base theme and I am extending it with custom theme

Download below bootstrap base theme

So for creating a custom theme by extending this base theme , you can see sample bootstrap theme in downloaded bootstrap theme.

Folder \starterkits contains a THEMENAME folder, which you can copy and place it in your custom themes folder.

Rename THEMENAME with your custom theme name.

So my custom theme template folder is empty. We are going to create templates files here.

First enable twig debug in local settings.

See this article for enabling twig debug.

Here I have added a content in Article content type.

Open article page.

Right click and click inspect in chrome browser.

Here you can see multiple node template suggestion.

Also you can see possible templates in below path in classy theme


Here we are customizing templates of article content type.

You can see the name node—article–full.html.twig

Next copy node.html.twig from bootstrap theme templates folder(\themes\contrib\bootstrap\templates\node\node.html.twig) and place it in your custom theme templates folder and rename to   node—article–full.html.twig

Clear the cache and load the newly added  article page. This article will be rendered through node—article—full.html.twig that we placed in our custom theme.

You can confirm this by placing a class name in a div in above template file.

I have placed below div in   node—article–full.html.twig file. Clear the cache. You can see this div in rendered article page.

<div class=”image-div”>


Next we are going to extract each fields in the node and give a wrapper div.

For printing variables and its contents, you can use kint or functions in Devel module.

Here in my Drupal 9 website I enabled Devel module and in Devel settings enabled Symfony var-dumper option.

If I use below function in template

{{ dpm()}}

We can see all variable and its values.

You can see field_image and body files inside content array.

So inside your article node template file remove  {{ content }}

Wrap your fields inside div tags as below.

<div class="img-class">
    {{ content['field_image'] }}
	<div class="body-class">
    {{ content['body'] }}


Clear the cache and reload the article page. You can see image and body wrapped inside div tags as below.

Below provided possible node fields templates


* field–node–field-image–article.html.twig

* field–node–field-image.html.twig

* field–node–article.html.twig

* field–field-image.html.twig

* field–image.html.twig

x field.html.twig


If you need to change mark up then only go for creating above templates. Else go for .theme hooks.

Adding class to img tag

You can use preprocess_image hook in .theme file.

function YOURTHEME_preprocess_image(&$variables) {

  // Check the image style.
  if ($variables['style_name'] == 'MYSTYLE') {

    // Set class.
    $variables['attributes']['class'][] = 'img-customstyle';


Adding class to other fields

you can use YOURTHEME_preprocess_field   preprocess function.

function YOURTHEME_preprocess_field(&$variables) {

  if ($variables['element']['#field_name'] == 'fielda_name') {

    // Set class.
    $variables['attributes']['class'][] = 'style-class';

Altering image fields in node

You can control img tag of the rendered image by  changing display format of image. Here got to  structure and edit article content type. You can see manage display as below. Change format to URL to image.

Flesh the cache and you will get image as  link text in template. So in field  template field–node–field-image–article.html.twig

{% for item in items %}

      <div class="image-article">{{ item.content }}</div>
{% endfor %}


item.content content is a url to the image.

In your .theme file you can use a variable value with base url  as below.

function YOURTHEME_preprocess(&$variables) {
	 $host = \Drupal::request()->getHost();
  $variables['base_path'] = $host;

SO in your twig file you can use s below to get full URL to

File- path\templates\node\field–node–field-image–article.html.twig

{% for item in items %}

      <div class="image-article">{{ base_path }}{{item.content }}</div>
{% endfor %}



Get Free E-book
Get a free Ebook on Drupal 8 -theme tutorial
I agree to have my personal information transfered to MailChimp ( more information )
if you like this article Buy me a Coffee this will be an ispiration for me to write articles like this.

You may also like...