Skip to main content

Document Renderer Module - Overview

Render plain text, Markdown, or HTML into PDF with no external services. All processing runs in-process using QuestPDF (.NET) or Puppeteer (Node.js). Supports branding, tenant isolation, and configurable styling.

Packages

  • .NET: PrimusSaaS.Documents (current: 2.0.0)
  • Node.js: @primus-saas/documents (current: 1.0.0)

Key Capabilities

  • Plain text, Markdown, and HTML input support
  • PDF output with customizable styling
  • Branded headers and footers
  • Tenant isolation with tenant ID in footer
  • Configurable page margins and font sizes
  • Self-test mode for validation

Example API

POST /api/documents/render
Payload:

{
"tenantId": "tenant-123",
"title": "Invoice",
"contentType": "markdown",
"content": "# Invoice\n\n- Amount: $100.00"
}

Response: application/pdf binary

Quick Install

# .NET
dotnet add package PrimusSaaS.Documents

# Node.js
npm install @primus-saas/documents puppeteer

Node.js Example

import { PuppeteerDocumentRenderer } from '@primus-saas/documents';

const renderer = new PuppeteerDocumentRenderer({
brandName: 'My Company',
includeTimestampInFooter: true,
});

const pdfBuffer = await renderer.renderPdf({
tenantId: 'tenant-123',
title: 'Monthly Report',
content: '# Report\n\n- Sales: $10,000',
contentType: 'markdown',
});

await renderer.close();

.NET Example

using Primus.Documents;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddPrimusDocumentRenderer(opts =>
builder.Configuration.GetSection("PrimusDocuments").Bind(opts));

var app = builder.Build();
app.MapControllers();
app.Run();

appsettings.json:

{
"PrimusDocuments": {
"BrandName": "Your Company",
"IncludeTimestampInFooter": true,
"PageMargin": 50
}
}

Controller Example

[HttpPost("render")]
public async Task<IActionResult> Render([FromBody] RenderDocumentRequest request)
{
var pdfBytes = await _renderer.RenderPdfAsync(request);
return File(pdfBytes, "application/pdf", "document.pdf");
}

Configuration Reference (PrimusDocuments)

Bind options from appsettings.json under PrimusDocuments:

{
"PrimusDocuments": {
"Provider": "Default",
"MaxContentLength": 20000,
"LinkTtl": "00:10:00",
"SelfTestEnabled": true,
"BrandName": "Your Company",
"IncludeTimestampInFooter": true,
"IncludeTenantInFooter": true,
"PageMargin": 50,
"BodyFontSize": 12,
"TitleFontSize": 24
}
}

Self-Test

Run a basic self-test to validate your renderer configuration.

using Primus.Documents.SelfTest;

var result = await _selfTest.RunAsync(SelfTestMode.Basic);
if (!result.Success)
{
_logger.LogError("Self-test failed: {Summary}", result.Summary);
}

Use It

Render a PDF directly from your service code.

var pdfBytes = await _renderer.RenderPdfAsync(new RenderDocumentRequest
{
TenantId = "tenant-123",
Title = "Invoice 001",
ContentType = DocumentContentType.Markdown,
Content = "# Invoice\nTotal: $500"
});

See Also