Dynamic contracts are a critical part of many data-driven applications. One of the most common examples is the non-disclosure agreement (NDA). While the structure of NDAs is fairly consistent, the content often needs to vary based on the business case, such as jurisdiction, clauses, or duration. In this article, we'll show you how to build a dynamic NDA generator using TX Text Control's MailMerge engine, with a focus on using merge blocks and the RemoveEmptyBlocks property to include or exclude entire sections of a document based on input data. Dynamic, Data-Driven Contracts The goal of this concept is to have a template with merge fields for dynamic data and also the ability to include specific sections in the agreement that are optional. With TX Text Control, you can create a single template that includes all possible sections and let the data itself control what is rendered. Hardcoding each variation would be inefficient and error-prone. Here's a breakdown of a typical NDA and the sections that can be dynamically controlled using merge fields or conditional blocks: Section Dynamic? Merge Fields / Conditions Introduction / Preamble No «effective_date» «disclosing_party.name» «disclosing_party.address» «receiving_party.name» «receiving_party.address» Purpose No «purpose» Definition of Confidential Information No Obligations of Receiving Party No Term and Termination Yes «term» «survival» Return or Destruction of Materials Yes Non-Compete and Non-Solicitation Yes «duration» Governing Law Yes «jurisdiction» Entire Agreement No Signatures Yes «disclosing_party.company «disclosing_party.name» «disclosing_party.title» «disclosing_party.date» «receiving_party.company» «receiving_party.name» «receiving_party.title» «receiving_party.date» Creating the Template The first part of the template looks very straightforward, with structured numbered lists and merge fields as placeholders where the actual data will be merged. Now let us look at the dynamic part of the contract template. The dynamic sections consist of merge blocks (highlighted in red by default) with optional merge fields. Using Merge Blocks Pay close attention to what is in the merge block. It includes the last carriage return line feed and an extra carriage return character, which is necessary because we may be removing content from a numbered list. So in both cases, whether the content remains or is removed, the list is perfectly intact. Using the MailMerge Engine For demonstration purposes, we will use the following JSON data as our sample data for the merge process. This JSON data contains all the data needed to include all the sections. [ { "effective_date": "2025-10-01", "disclosing_party": { "name": "Company A", "address": "1234 Elm St, Springfield, IL 62701" }, "receiving_party": { "name": "Company B", "address": "5678 Oak St, Springfield, IL 62702" }, "purpose": "the evaluating of a potential business relationship", "section_return": {}, "section_compete": { "duration": 12 }, "section_law": { "jurisdiction": "Illinois" }, "section_signatures": { "disclosing_party": { "company": "Company A", "name": "John Doe", "title": "CEO", "date": "2025-10-01" }, "receiving_party": { "company": "Company B", "name": "Jane Smith", "title": "CFO", "date": "2025-10-01" } } } ] The following code is required to merge the JSON data into the template using the MailMerge class. using TXTextControl.DocumentServer; using TXTextControl; using ServerTextControl tx = new(); // Create a new document instance in memory tx.Create(); // Load NDA template (TX Text Control format) tx.Load("Data/nda_template.tx", StreamType.InternalUnicodeFormat); // Load JSON data for MailMerge from file string jsonData = File.ReadAllText("Data/nda_data.json"); // Initialize MailMerge with the document MailMerge mailMerge = new() { TextComponent = tx, RemoveEmptyBlocks = true, // Removes blocks that remain empty after merge }; // Track merged block names List<string> blockNames = new(); mailMerge.BlockMerging += (sender, e) => { blockNames.Add(e.BlockName); }; // Merge JSON data into the loaded template mailMerge.MergeJsonData(jsonData); // Export the filled NDA to a PDF file tx.Save("results.pdf", StreamType.AdobePDF); // Output result to console Console.WriteLine(blockNames.Count > 0 ? $"Merged {blockNames.Count} blocks: {string.Join(", ", blockNames)}" : "No blocks were merged."); If you use the full JSON with all sections, the output should be this and a PDF is generated. Merged 5 blocks: section_signatures, section_law, section_compete, section_return, section_term In the created PDF you can see that all merge fields are filled and all sections are included. Removing Sections Now let's remove the section_term and section_compete sections from the JSON and merge it back together. The JSON now looks like this: [ { "effective_date": "2025-10-01", "disclosing_party": { "name": "Company A", "address": "1234 Elm St, Springfield, IL 62701" }, "receiving_party": { "name": "Company B", "address": "5678 Oak St, Springfield, IL 62702" }, "purpose": "the evaluating of a potential business relationship", "section_return": {}, "section_law": { "jurisdiction": "Illinois" }, "section_signatures": { "disclosing_party": { "company": "Company A", "name": "John Doe", "title": "CEO", "date": "2025-10-01" }, "receiving_party": { "company": "Company B", "name": "Jane Smith", "title": "CFO", "date": "2025-10-01" } } } ] And the output is this: Merged 3 blocks: section_signatures, section_law, section_return As you can see, the sections are removed from the PDF and the list is still intact. The result is a perfectly designed contract that is completely dynamic and 100% controlled by the data. Benefits of This Approach This approach allows you to create a single template that can handle multiple variations of a contract. This reduces the need for multiple templates and simplifies the contract creation process. It also allows for easy updates to the template without having to modify multiple files. Reusability: One template covers hundreds of NDA variations. Accuracy: Reduces manual errors by automating document assembly. Efficiency: Generate a polished, branded NDA in seconds. Flexibility: Easily update legal language across all generated NDAs. Conclusion In summary, using TX Text Control's MailMerge engine with dynamic merge blocks allows you to create flexible and efficient contracts that can adapt to different business needs. This not only saves time, but also ensures that your contracts are always up to date and compliant with the latest legal standards. The sample code and templates provided in this article can be used as a starting point for your own NDA generator. Feel free to modify the template and JSON data to suit your specific requirements.