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
- Document Renderer Quick Start
- Document Renderer Advanced
- Multi-Tenancy (tenant isolation)