# Text templating node

**URL:** <https://community.n8n.io/t/text-templating-node/1965>\
**Category:** Feature Requests\
**Created:** [August 4, 2020, 8:49pm UTC](https://community.n8n.io/t/text-templating-node/1965 "2020-08-04T20:49:24Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![trygvis](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@trygvis](https://community.n8n.io/u/trygvis)\
**Post date:** [August 4, 2020, 8:49pm UTC](https://community.n8n.io/t/text-templating-node/1965/1 "2020-08-04T20:49:24Z")

</div>

Hi

I’m creating Slack messages based on a different data inputs, so the expression used becomes kinda hard to read/write. There are times where I want to have if/else blocks depending on the incoming data etc. I imagine could be useful when composing emails and such too.

Is there a better way of doing this now other than just using the build-in expressions?

Would it be useful to have a node for explicitly generating the text, then the Slack node would just do the slack stuff and testing becomes easier too (then I don’t have to spam the Slack channel to test everything).

If n8n had been a Python project I would have suggested to use Jinja2.

It would also be awesome if the node would allow me to test the template with different input objects too.

---

<div class="post-metadata">

**Author:** ![jan](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/jan/32/9_2.png) [@jan](https://community.n8n.io/u/jan)\
**Post date:** [August 4, 2020, 8:54pm UTC](https://community.n8n.io/t/text-templating-node/1965/2 "2020-08-04T20:54:27Z")

</div>

That should be possible with for example the Set-Node unless I understand you wrong.

---

<div class="post-metadata">

**Author:** ![Tephlon](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/tephlon/32/9899_2.png) [@Tephlon](https://community.n8n.io/u/Tephlon)\
**Post date:** [August 4, 2020, 9:15pm UTC](https://community.n8n.io/t/text-templating-node/1965/3 "2020-08-04T21:15:16Z")

</div>

It looks like [Nunjucks](http://mozilla.github.io/nunjucks/) is a viable alternative to Jinja2. I wonder if there is an enterprising community member that would be interested in taking up the challenge of creating a Numjucks node?

---

<div class="post-metadata">

**Author:** ![jan](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/jan/32/9_2.png) [@jan](https://community.n8n.io/u/jan)\
**Post date:** [August 4, 2020, 9:38pm UTC](https://community.n8n.io/t/text-templating-node/1965/4 "2020-08-04T21:38:44Z")

</div>

Nunjucks looks very interesting! But am not sure if a specific node would be the best here as I can see that it can be helpful on very many different nodes. Meaning making something like it available generally in expressions could be easier and would avoid making workflows unnecessarily more complicated by having to add additional nodes to use it.

---

<div class="post-metadata">

**Author:** ![Tephlon](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/tephlon/32/9899_2.png) [@Tephlon](https://community.n8n.io/u/Tephlon)\
**Post date:** [August 4, 2020, 10:31pm UTC](https://community.n8n.io/t/text-templating-node/1965/5 "2020-08-04T22:31:42Z")

</div>

@jan, I never even thought about using templating as a base structure within n8n. Makes a lot of sense.

I know I have used other tools in the past that used [mustache](https://github.com/janl/mustache.js) for a templating engine and it was very easy and intuitive to use. If n8n were to go beyond the scope of a simple node, then I would suggest taking a look at a few different templating systems before moving forward (like you didn’t have enought to do, @jan) .

Here is a list of a few common ones:

- [doT](https://olado.github.io/doT/)
- [ECT](http://ectjs.com/)
- [EJS](http://ejs.co/)
- [Handlebars](http://handlebarsjs.com/)
- [Jade Language](http://jade-lang.com/)
- [jQuery Templating](https://codepb.github.io/jquery-template/)
- [JsRender](https://www.jsviews.com/#jsrender)
- [Marko](https://markojs.com/)
- [Mustache](https://mustache.github.io/)
- [Nunjucks](https://mozilla.github.io/nunjucks/)
- [Pug](https://pugjs.org/)
- [Squirrelly](https://squirrelly.js.org/)
- [Template7](http://www.idangero.us/template7/)
- [Underscore](http://underscorejs.org/)

---

<div class="post-metadata">

**Author:** ![jan](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/jan/32/9_2.png) [@jan](https://community.n8n.io/u/jan)\
**Post date:** [August 5, 2020, 6:04am UTC](https://community.n8n.io/t/text-templating-node/1965/6 "2020-08-05T06:04:54Z")

</div>

Thanks a lot @Tephlon for that great list. Will make researching options much easier and faster.

---

<div class="post-metadata">

**Author:** ![trygvis](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@trygvis](https://community.n8n.io/u/trygvis)\
**Post date:** [August 5, 2020, 9:28am UTC](https://community.n8n.io/t/text-templating-node/1965/7 "2020-08-05T09:28:32Z")

</div>

I think having a special node would be a good thing, but it doesn’t have to be either or.

1. It would only be used when a more power-full templating system than the build-in n8n expressions can give and and 2) the other nodes can be simpler as they don’t have to think/know about the more advanced templating features.

---

<div class="post-metadata">

**Author:** ![erbg](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/erbg/32/14953_2.png) [@erbg](https://community.n8n.io/u/erbg)\
**Post date:** [October 5, 2020, 8:43pm UTC](https://community.n8n.io/t/text-templating-node/1965/8 "2020-10-05T20:43:46Z")

</div>

Hello,

I just created a [PR](https://github.com/n8n-io/n8n/pull/1016) with a Text Template Node. For now, it implements mustache and handlebar, but could be extended with another engine very quickly.

Hope it is what you were thinking of.

---

<div class="post-metadata">

**Author:** ![trygvis](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@trygvis](https://community.n8n.io/u/trygvis)\
**Post date:** [October 7, 2020, 2:11pm UTC](https://community.n8n.io/t/text-templating-node/1965/9 "2020-10-07T14:11:51Z")

</div>

Sounds like it, I’m hoping that it will get merged!

---

<div class="post-metadata">

**Author:** ![Axel](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/axel/32/1885_2.png) [@Axel](https://community.n8n.io/u/Axel)\
**Post date:** [October 8, 2020, 1:22pm UTC](https://community.n8n.io/t/text-templating-node/1965/10 "2020-10-08T13:22:59Z")

</div>

I added a comment to the PR.

@erbg Perhaps you can take a look into it.

---

<div class="post-metadata">

**Author:** ![jan](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/jan/32/9_2.png) [@jan](https://community.n8n.io/u/jan)\
**Post date:** [November 6, 2020, 1:11pm UTC](https://community.n8n.io/t/text-templating-node/1965/11 "2020-11-06T13:11:41Z")

</div>

Btw. posted here a temporary work-around with handlebars:

> [@Passing function node output as one item](http://community.n8n.io/t/passing-function-node-output-as-one-item/2951/8):
>
> As a temporary workaround is the same already possible in the Function-Node. If you start n8n with the following environment variable to make sure that handlebars can be used: export NODE\_FUNCTION\_ALLOW\_EXTERNAL=handlebars Then you can do the following:

---

<div class="post-metadata">

**Author:** ![angel](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/angel/32/2911_2.png) [@angel](https://community.n8n.io/u/angel)\
**Post date:** [June 29, 2021, 8:45pm UTC](https://community.n8n.io/t/text-templating-node/1965/12 "2021-06-29T20:45:22Z")

</div>

I see the [PR](https://github.com/n8n-io/n8n/pull/1016) was closed and it was not added. Anything we can do as users to get more visibility on this node based integration of Handlebars? Thanks for your time.

---

<div class="post-metadata">

**Author:** ![Aracon](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/aracon/32/6439_2.png) [@Aracon](https://community.n8n.io/u/Aracon)\
**Post date:** [August 31, 2021, 9:11am UTC](https://community.n8n.io/t/text-templating-node/1965/13 "2021-08-31T09:11:44Z")

</div>

Why the PR was closed? The templating node seems really helpful.

---

<div class="post-metadata">

**Author:** ![trygvis](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@trygvis](https://community.n8n.io/u/trygvis)\
**Post date:** [August 31, 2021, 12:53pm UTC](https://community.n8n.io/t/text-templating-node/1965/14 "2021-08-31T12:53:33Z")

</div>

What I’ve always ended up doing here is to just use the Function/Function Item nodes and do the templating with code. For my small Slack messages that has been as easy as using Handlebars.

The output from this code can be put straight into a Slack message post:

```auto
let json = {}

let slack_links = [];

for (let item of items) {
// let i = items[item];
  let i = item;
  console.log("item");
  console.log(JSON.stringify(item));
  let id = i.json.id;
  let name = i.json.name;
  let url = `https://docs.google.com/spreadsheets/d/${id}`
  slack_links.push(`\u2022 <${url}|${name}>\n`);
}

json.slack = "Reports created:\n" + slack_links;

return [{json: json}];

```

---

<div class="post-metadata">

**Author:** ![jan](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/jan/32/9_2.png) [@jan](https://community.n8n.io/u/jan)\
**Post date:** [August 31, 2021, 12:59pm UTC](https://community.n8n.io/t/text-templating-node/1965/15 "2021-08-31T12:59:58Z")

</div>

Here also another example with a Function-Node and Handlebars:

> [@Passing function node output as one item](http://community.n8n.io/t/passing-function-node-output-as-one-item/2951/8):
>
> As a temporary workaround is the same already possible in the Function-Node. If you start n8n with the following environment variable to make sure that handlebars can be used: export NODE\_FUNCTION\_ALLOW\_EXTERNAL=handlebars Then you can do the following:

---

<div class="post-metadata">

**Author:** ![trygvis](https://avatars.discourse-cdn.com/v4/letter/t/ea5d25/32.png) [@trygvis](https://community.n8n.io/u/trygvis)\
**Post date:** [August 31, 2021, 1:01pm UTC](https://community.n8n.io/t/text-templating-node/1965/16 "2021-08-31T13:01:16Z")

</div>

How is it possible to require() handlebars? Does the n8n package already depend on handlebars so it happens to be available?

---

<div class="post-metadata">

**Author:** ![jan](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/jan/32/9_2.png) [@jan](https://community.n8n.io/u/jan)\
**Post date:** [September 4, 2021, 3:47pm UTC](https://community.n8n.io/t/text-templating-node/1965/17 "2021-09-04T15:47:38Z")

</div>

Almost. Not a direct n8n dependency, it is rather a dependency of an n8n-dependency.

---

<div class="post-metadata">

**Author:** ![Radiergummi](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/radiergummi/32/6639_2.png) [@Radiergummi](https://community.n8n.io/u/Radiergummi)\
**Post date:** [September 15, 2021, 3:05pm UTC](https://community.n8n.io/t/text-templating-node/1965/18 "2021-09-15T15:05:56Z")

</div>

It would be cool if expressions were parsed by a templating engine, especially Nunjucks - it would fit n8n perfectly. Adding it should be fully backwards compatible, but everyone suddenly could use advanced templating logic or filters:

```nohighlight
{{ $node["Set"].json["names"] | slice(0, 3) | join(",") }}

```

It would both eliminate the need for a templating node and make every single expression more powerful, without sacrificing ergonomics 🙂

---

<div class="post-metadata">

**Author:** ![llmx](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/llmx/32/137771_2.png) [@llmx](https://community.n8n.io/u/llmx)\
**Post date:** [November 11, 2025, 6:48pm UTC](https://community.n8n.io/t/text-templating-node/1965/19 "2025-11-11T18:48:50Z")

</div>

Good day everyone 👋

I stumbled upon exactly same issue this month so I made a custom node: [GitHub - llmx-de/n8n-nodes-text-templater: N8N node for dynamic text templating using Mustache, Handlebars, Nunjucks, and EJS engines - perfect for AI prompts, email automation, and report generation](https://github.com/llmx-de/n8n-nodes-text-templater) (in case code block doesn’t give that comfort

Or on npm: [https://www.npmjs.com/package/n8n-nodes-text-templater](https://www.npmjs.com/package/n8n-nodes-text-templater)

It allows to pick template engine and pass variables.
