You are currently offline, serving cached version


The paragraph-placeholder module allows to simply repeat or show hide a given paragraph, shape, depending on a condition.

It allows you to hide or show a paragraph or shape (using true/false) or repeat a paragraph or shape (using an array).


Your docx should contain the text: {?data}. After installing the module, you can use a working demo by running node sample.js.

When a tag beginning with a question mark (?) is found, the tag value is calculated.

If the tag value is :

  • falsy the whole paragraph containing the tag is removed.

  • true, the paragraph is kept but the tag is replaced to "".

  • an array, the paragraph will be duplicated for each element in the array.

    For example, you can write :

    - {?users}User {user} likes {sport}

    With following data :

        users: [
                user: "John",
                sport: "Golf",
                user: "Mary",
                sport: "Kickboxing",

    Will render

    - User John likes Golf
    - User Mary likes Kickboxing
  • a string, the tag is replaced normally and the paragraph is kept. Hello {?user} will render Hello John if the data is { user: "John" }

  • an object, the tag is replaced normally and the paragraph is kept.

If there are multiple "paragraph placeholder" tags in the same paragraph, the paragraph will be removed if one of the values is falsy. Only if all values are truthy, the paragraph is kept.

For arrays, it is also possible to use arrays that contain just string values, for example :

- {?users}

With a value of {users: ["John", "Jack", "Mary" ]} will now render :

- John
- Jack
- Mary

Usage (nodejs)

const PPModule = require("docxtemplater-pp-module");
const fs = require("fs");

const zip = new PizZip(fs.readFileSync("input.docx"));
const doc = new Docxtemplater(zip, {
    modules: [new PPModule({})],

    company_name: "Acme Corp",
    company_shareprice: 20.93,

const buffer = doc.getZip().generate({
    type: "nodebuffer",
    compression: "DEFLATE",

fs.writeFile("test.docx", buffer);

Usage (browser)

In the browser, use following html file :

    <script src="node_modules/docxtemplater/build/docxtemplater.js"></script>
    <script src="node_modules/pizzip/dist/pizzip.js"></script>
    <script src="node_modules/pizzip/vendor/FileSaver.js"></script>
    <script src="node_modules/pizzip/dist/pizzip-utils.js"></script>
    <script src="build/pp-module.js"></script>
            function (error, content) {
                if (error) {

                const zip = new PizZip(content);
                const doc = new docxtemplater(zip, {
                    modules: [new DocxtemplaterPPModule({})],

                    company_name: "Acme Corp",
                    company_shareprice: 20.93,
                const out = doc.getZip().generate({
                    type: "blob",
                saveAs(out, "generated.docx");


It is possible to show or hide a shape in a diagram using this module, simply with this template :

Shape Show/Hide Demo
Show or hide a shape using the {?cond1} tag

    cond1: false,
    cond2: true,
    user: "John",
    employer: "Mary",
    name: "Max",

Shape Show/Hide Demo Result
Result document



Make it possible to use prefix from the constructor


Add typescript typings to be able to change the module prefix


Upgrade module to use NodeNext moduleResolution setting. See explanation here


Use new resolvedId API => requires docxtemplater@3.43.0


Fix bug when using renderAsync and parser compilation fails : the error should now be shown inside a multierror. To to this, we know use sm.getValueAsync in resolve instead of sm.getValue


Use sm.getValueAsync in resolve : fixes a bug if the parser fails


Set module.priority in order to have no more issues related to module ordering


Upgrade to correctly pass in fileType, contentType, … to resolve

Makes it compatible with docxtemplater 3.40.1


Add module.clone() internal to make module work well with subsegment module


Add support for loops in the module :

- {?users}{name} likes {hobby}


Add support, for shapes, which allows to show or hide a shape.


When using this module with the docxtemplater option {linebreaks: true}, the rendered elements will also contain linebreaks.


When using this module in async mode inside a loop, the following message would appear :

TypeError: Cannot read properties of undefined (reading 'value')
at ScopeManager.\_getValue (.../paragraph-placeholder/node_modules/docxtemplater/js/scope-manager.js:49:7)

Now, the module works well even when the tag is placed inside a loop.


Make module compatible with docxtemplater@3.28.0. Please make sure to update docxtemplater to 3.28.0 at the same time you update this module. The internal change made is the use of the new matchers API which fixes bugs that were triggered depending on the order of the modules that are attached to the instance. Now the order of the modules should not matter as expected.


Use @xmldom/xmldom instead of xmldom, see this github issue


Generate files in built with correct filename In previous versions, the filename was always build/docxtemplater.js. Now the filename is build/pp-module.js The .min.js file is also created now.


Add typescript definitions for public API


Bugfix "Cannot read property 'offset' of undefined, when using multiple paragraph placeholder tags in the same paragraph


Declare supportedFileTypes, which allows to use this module with the new docxtemplater constructor which was introduced in docxtemplater 3.17.


Hide value if value === true (in that case, show the paragraph but don't display any value)


Add support for pptx format (Powerpoint files)


Initial release

Talk with sales Contact us