Xamarin PDF Generator: Build Mobile PDF Apps with IronPDF
Creating PDF files in Xamarin.Forms can be tricky. Most .NET PDF libraries do not directly support mobile apps, and trying to generate PDF documents on a device often leads to errors or missing functionality. That's where IronPDF steps in.
While IronPDF does not run natively inside a Xamarin.Forms app, a server-side API approach bridges that gap cleanly. Your mobile app sends HTML content to the API and receives finished PDF files in return -- giving you access to professional PDF generation including forms, headers, footers, images, and custom layouts.
Important note: Microsoft ended support for Xamarin in May 2024. For new projects, .NET MAUI is the recommended successor and supports IronPDF more directly. This guide covers the server-side pattern for legacy Xamarin projects still in maintenance and explains the migration path to MAUI for teams starting fresh.
Why Does a Server-Side Approach Work for Mobile PDF Generation?
IronPDF excels at converting HTML content into polished PDF documents with full support for CSS, JavaScript, and complex layouts. Running IronPDF on a dedicated server -- rather than inside a mobile application -- sidesteps the platform constraints that prevent direct on-device PDF rendering on iOS and Android.
The server-side pattern offers several concrete advantages:
- Consistent output: Fonts, images, and CSS are resolved server-side, eliminating rendering differences between Android and iOS hardware.
- Feature access: IronPDF features such as PDF form creation, digital signatures, watermarks, and multi-page layouts are all available on the server without restriction.
- Lighter mobile app: The device only sends an HTTP request and stores the returned PDF bytes -- no heavy PDF engine runs on the phone.
- Centralized licensing: A single IronPDF license covers your server deployment rather than licensing each device separately.
The Xamarin.Forms client calls the API, receives a byte array, writes it to local storage, and optionally opens a PDF viewer. The server handles everything else.
How Do You Set Up an IronPDF PDF Generation API?
Start by creating an ASP.NET Core Web API project. This is a standard .NET 10 minimal API that you can host anywhere -- Azure App Service, AWS, an on-premise server, or a Docker container.
Install IronPDF
Install IronPDF from NuGet using either of these commands:
Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
Create the PDF Controller
With IronPDF installed, add a controller that accepts HTML and returns a PDF:
using IronPdf;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
namespace PdfGenerationApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
[HttpPost("generate")]
public async Task<IActionResult> GeneratePdf([FromBody] PdfRequest request)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlContent);
return File(pdf.BinaryData, "application/pdf", "document.pdf");
}
}
public class PdfRequest
{
public string HtmlContent { get; set; } = string.Empty;
}
}
using IronPdf;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
namespace PdfGenerationApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
[HttpPost("generate")]
public async Task<IActionResult> GeneratePdf([FromBody] PdfRequest request)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlContent);
return File(pdf.BinaryData, "application/pdf", "document.pdf");
}
}
public class PdfRequest
{
public string HtmlContent { get; set; } = string.Empty;
}
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc
Dim builder = WebApplication.CreateBuilder(args)
builder.Services.AddControllers()
Dim app = builder.Build()
app.MapControllers()
app.Run()
Namespace PdfGenerationApi.Controllers
<ApiController>
<Route("api/[controller]")>
Public Class PdfController
Inherits ControllerBase
<HttpPost("generate")>
Public Async Function GeneratePdf(<FromBody> request As PdfRequest) As Task(Of IActionResult)
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 25
renderer.RenderingOptions.MarginBottom = 25
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(request.HtmlContent)
Return File(pdf.BinaryData, "application/pdf", "document.pdf")
End Function
End Class
Public Class PdfRequest
Public Property HtmlContent As String = String.Empty
End Class
End Namespace
ChromePdfRenderer uses a Chromium-based engine to render HTML exactly as a modern browser would. The HTML to PDF conversion respects CSS animations, embedded fonts, SVG graphics, and JavaScript-generated content. Paper size and margin settings translate directly into the final document layout.
Add Headers and Footers
For professional documents, add headers and footers before calling the renderer:
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:12px; color:#555;'>Confidential -- Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:center; font-size:11px;'>Generated by MyCompany App</div>"
};
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:12px; color:#555;'>Confidential -- Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:center; font-size:11px;'>Generated by MyCompany App</div>"
};
Imports System
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='text-align:right; font-size:12px; color:#555;'>Confidential -- Page {page} of {total-pages}</div>",
.DrawDividerLine = True
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='text-align:center; font-size:11px;'>Generated by MyCompany App</div>"
}
Page number tokens like {page} and {total-pages} are resolved automatically at render time.
How Do You Implement the Xamarin Client?
In the Xamarin.Forms application, create a service class that calls the API. Keep the service lean -- its only job is to serialize the HTML payload, send it, and return the raw PDF bytes to the caller.
using System.Net.Http;
using System.Text;
using System.Text.Json;
namespace XamarinPdfApp.Services
{
public class PdfService
{
private readonly HttpClient _httpClient;
private const string ApiUrl = "https://your-api.example.com/api/pdf/generate";
public PdfService()
{
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(60)
};
}
public async Task<byte[]> GeneratePdfAsync(string htmlContent)
{
var payload = new { HtmlContent = htmlContent };
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(ApiUrl, content);
if (response.IsSuccessStatusCode)
return await response.Content.ReadAsByteArrayAsync();
var error = await response.Content.ReadAsStringAsync();
throw new InvalidOperationException($"PDF generation failed ({(int)response.StatusCode}): {error}");
}
}
}
using System.Net.Http;
using System.Text;
using System.Text.Json;
namespace XamarinPdfApp.Services
{
public class PdfService
{
private readonly HttpClient _httpClient;
private const string ApiUrl = "https://your-api.example.com/api/pdf/generate";
public PdfService()
{
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(60)
};
}
public async Task<byte[]> GeneratePdfAsync(string htmlContent)
{
var payload = new { HtmlContent = htmlContent };
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(ApiUrl, content);
if (response.IsSuccessStatusCode)
return await response.Content.ReadAsByteArrayAsync();
var error = await response.Content.ReadAsStringAsync();
throw new InvalidOperationException($"PDF generation failed ({(int)response.StatusCode}): {error}");
}
}
}
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Namespace XamarinPdfApp.Services
Public Class PdfService
Private ReadOnly _httpClient As HttpClient
Private Const ApiUrl As String = "https://your-api.example.com/api/pdf/generate"
Public Sub New()
_httpClient = New HttpClient With {
.Timeout = TimeSpan.FromSeconds(60)
}
End Sub
Public Async Function GeneratePdfAsync(htmlContent As String) As Task(Of Byte())
Dim payload = New With {Key .HtmlContent = htmlContent}
Dim json = JsonSerializer.Serialize(payload)
Dim content = New StringContent(json, Encoding.UTF8, "application/json")
Dim response = Await _httpClient.PostAsync(ApiUrl, content)
If response.IsSuccessStatusCode Then
Return Await response.Content.ReadAsByteArrayAsync()
End If
Dim error = Await response.Content.ReadAsStringAsync()
Throw New InvalidOperationException($"PDF generation failed ({CInt(response.StatusCode)}): {error}")
End Function
End Class
End Namespace
A 60-second timeout accommodates complex HTML documents with many images or CSS resources. For very large files, consider returning a presigned download URL from the API instead of streaming the binary directly -- this keeps mobile memory usage predictable.
How Do You Save and Open PDF Files on Device?
Once the service returns the byte array, write it to device storage and open it in the platform PDF viewer. Xamarin.Forms uses the DependencyService pattern to call platform-specific implementations.
Define the interface in shared code:
using System.Threading.Tasks;
namespace XamarinPdfApp.Interfaces
{
public interface ISaveFile
{
Task<string> SavePdfAsync(string filename, byte[] pdfData);
}
}
using System.Threading.Tasks;
namespace XamarinPdfApp.Interfaces
{
public interface ISaveFile
{
Task<string> SavePdfAsync(string filename, byte[] pdfData);
}
}
Imports System.Threading.Tasks
Namespace XamarinPdfApp.Interfaces
Public Interface ISaveFile
Function SavePdfAsync(filename As String, pdfData As Byte()) As Task(Of String)
End Interface
End Namespace
Register the iOS implementation using DependencyService:
using Foundation;
using QuickLook;
using UIKit;
using XamarinPdfApp.Interfaces;
using Xamarin.Forms;
[assembly: Dependency(typeof(XamarinPdfApp.iOS.SaveFileIOS))]
namespace XamarinPdfApp.iOS
{
public class SaveFileIOS : ISaveFile
{
public async Task<string> SavePdfAsync(string filename, byte[] pdfData)
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filePath = System.IO.Path.Combine(documents, filename);
await System.IO.File.WriteAllBytesAsync(filePath, pdfData);
return filePath;
}
}
}
using Foundation;
using QuickLook;
using UIKit;
using XamarinPdfApp.Interfaces;
using Xamarin.Forms;
[assembly: Dependency(typeof(XamarinPdfApp.iOS.SaveFileIOS))]
namespace XamarinPdfApp.iOS
{
public class SaveFileIOS : ISaveFile
{
public async Task<string> SavePdfAsync(string filename, byte[] pdfData)
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filePath = System.IO.Path.Combine(documents, filename);
await System.IO.File.WriteAllBytesAsync(filePath, pdfData);
return filePath;
}
}
}
Imports Foundation
Imports QuickLook
Imports UIKit
Imports XamarinPdfApp.Interfaces
Imports Xamarin.Forms
<Assembly: Dependency(GetType(XamarinPdfApp.iOS.SaveFileIOS))>
Namespace XamarinPdfApp.iOS
Public Class SaveFileIOS
Implements ISaveFile
Public Async Function SavePdfAsync(filename As String, pdfData As Byte()) As Task(Of String) Implements ISaveFile.SavePdfAsync
Dim documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim filePath = System.IO.Path.Combine(documents, filename)
Await System.IO.File.WriteAllBytesAsync(filePath, pdfData)
Return filePath
End Function
End Class
End Namespace
For Android, write to the app's external files directory and register a FileProvider in the manifest so you can hand the URI to a PDF viewer intent. The DependencyService.Get<ISaveFile>() call in shared code retrieves whichever implementation is registered for the current platform at runtime.
Wiring It All Together
In your Xamarin.Forms page or ViewModel, combine the service and the platform saver:
var htmlContent = BuildInvoiceHtml(invoice);
var pdfBytes = await _pdfService.GeneratePdfAsync(htmlContent);
var saver = DependencyService.Get<ISaveFile>();
var filePath = await saver.SavePdfAsync("invoice.pdf", pdfBytes);
await Launcher.OpenAsync(new OpenFileRequest
{
File = new ReadOnlyFile(filePath, "application/pdf")
});
var htmlContent = BuildInvoiceHtml(invoice);
var pdfBytes = await _pdfService.GeneratePdfAsync(htmlContent);
var saver = DependencyService.Get<ISaveFile>();
var filePath = await saver.SavePdfAsync("invoice.pdf", pdfBytes);
await Launcher.OpenAsync(new OpenFileRequest
{
File = new ReadOnlyFile(filePath, "application/pdf")
});
Dim htmlContent = BuildInvoiceHtml(invoice)
Dim pdfBytes = Await _pdfService.GeneratePdfAsync(htmlContent)
Dim saver = DependencyService.Get(Of ISaveFile)()
Dim filePath = Await saver.SavePdfAsync("invoice.pdf", pdfBytes)
Await Launcher.OpenAsync(New OpenFileRequest With {
.File = New ReadOnlyFile(filePath, "application/pdf")
})
This opens the saved PDF in whatever viewer the user has installed, which is typically a native PDF application on both iOS and Android.
How Do You Generate Professional Invoice and Report PDFs?
The quality of a PDF depends almost entirely on the quality of the HTML template passed to the renderer. Use C# string interpolation or a templating library like Scriban to build data-driven HTML:
public string BuildInvoiceHtml(Invoice invoice)
{
var rows = string.Join(
"\n",
invoice.Items.Select(i =>
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td><td>${i.UnitPrice:F2}</td><td>${i.Total:F2}</td></tr>"
)
);
return $@"<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<style>
body {{ font-family: Arial, sans-serif; color: #333; margin: 0; padding: 30px; }}
h1 {{ color: #1a73e8; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
th {{ background: #1a73e8; color: #fff; padding: 10px; text-align: left; }}
td {{ padding: 10px; border-bottom: 1px solid #e0e0e0; }}
.total {{ font-weight: bold; font-size: 1.1em; text-align: right; margin-top: 15px; }}
</style>
</head>
<body>
<h1>Invoice #{invoice.Number}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd} | Due: {invoice.DueDate:yyyy-MM-dd}</p>
<p>Bill to: <strong>{invoice.ClientName}</strong></p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr></thead>
<tbody>{rows}</tbody>
</table>
<p class='total'>Grand Total: ${invoice.GrandTotal:F2}</p>
</body>
</html>";
}
public string BuildInvoiceHtml(Invoice invoice)
{
var rows = string.Join(
"\n",
invoice.Items.Select(i =>
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td><td>${i.UnitPrice:F2}</td><td>${i.Total:F2}</td></tr>"
)
);
return $@"<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<style>
body {{ font-family: Arial, sans-serif; color: #333; margin: 0; padding: 30px; }}
h1 {{ color: #1a73e8; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
th {{ background: #1a73e8; color: #fff; padding: 10px; text-align: left; }}
td {{ padding: 10px; border-bottom: 1px solid #e0e0e0; }}
.total {{ font-weight: bold; font-size: 1.1em; text-align: right; margin-top: 15px; }}
</style>
</head>
<body>
<h1>Invoice #{invoice.Number}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd} | Due: {invoice.DueDate:yyyy-MM-dd}</p>
<p>Bill to: <strong>{invoice.ClientName}</strong></p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr></thead>
<tbody>{rows}</tbody>
</table>
<p class='total'>Grand Total: ${invoice.GrandTotal:F2}</p>
</body>
</html>";
}
Imports System
Imports System.Linq
Public Function BuildInvoiceHtml(invoice As Invoice) As String
Dim rows = String.Join(
vbLf,
invoice.Items.Select(Function(i)
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td><td>${i.UnitPrice:F2}</td><td>${i.Total:F2}</td></tr>"
)
)
Return $"
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<style>
body {{ font-family: Arial, sans-serif; color: #333; margin: 0; padding: 30px; }}
h1 {{ color: #1a73e8; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
th {{ background: #1a73e8; color: #fff; padding: 10px; text-align: left; }}
td {{ padding: 10px; border-bottom: 1px solid #e0e0e0; }}
.total {{ font-weight: bold; font-size: 1.1em; text-align: right; margin-top: 15px; }}
</style>
</head>
<body>
<h1>Invoice #{invoice.Number}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd} | Due: {invoice.DueDate:yyyy-MM-dd}</p>
<p>Bill to: <strong>{invoice.ClientName}</strong></p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr></thead>
<tbody>{rows}</tbody>
</table>
<p class='total'>Grand Total: ${invoice.GrandTotal:F2}</p>
</body>
</html>"
End Function
The ChromePdfRenderer renders this template exactly as a browser would. You can add watermarks using IronPDF's watermark API or apply custom watermark designs for confidential drafts. For documents requiring a signature field, IronPDF's signing support lets you embed digital signature placeholders server-side.
How Do You Handle PDF Forms in a Xamarin App?
PDF forms are a common requirement for mobile business apps -- contracts, onboarding questionnaires, and inspection checklists all benefit from pre-filled editable fields. The server API can accept field data alongside the HTML template and embed form values before returning the PDF:
[HttpPost("form")]
public async Task<IActionResult> GenerateForm([FromBody] FormRequest request)
{
var renderer = new ChromePdfRenderer();
// Render an HTML form template to create an interactive PDF form
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlTemplate);
// Fill known values before returning
var form = pdf.Form;
foreach (var field in request.FieldValues)
{
var pdfField = form.Fields.FirstOrDefault(f => f.Name == field.Key);
if (pdfField is IronPdf.Forms.PdfFormTextFieldField textField)
textField.Value = field.Value;
}
return File(pdf.BinaryData, "application/pdf", "form.pdf");
}
[HttpPost("form")]
public async Task<IActionResult> GenerateForm([FromBody] FormRequest request)
{
var renderer = new ChromePdfRenderer();
// Render an HTML form template to create an interactive PDF form
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlTemplate);
// Fill known values before returning
var form = pdf.Form;
foreach (var field in request.FieldValues)
{
var pdfField = form.Fields.FirstOrDefault(f => f.Name == field.Key);
if (pdfField is IronPdf.Forms.PdfFormTextFieldField textField)
textField.Value = field.Value;
}
return File(pdf.BinaryData, "application/pdf", "form.pdf");
}
Imports Microsoft.AspNetCore.Mvc
Imports IronPdf
<HttpPost("form")>
Public Async Function GenerateForm(<FromBody> request As FormRequest) As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
' Render an HTML form template to create an interactive PDF form
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(request.HtmlTemplate)
' Fill known values before returning
Dim form = pdf.Form
For Each field In request.FieldValues
Dim pdfField = form.Fields.FirstOrDefault(Function(f) f.Name = field.Key)
If TypeOf pdfField Is IronPdf.Forms.PdfFormTextFieldField Then
Dim textField = DirectCast(pdfField, IronPdf.Forms.PdfFormTextFieldField)
textField.Value = field.Value
End If
Next
Return File(pdf.BinaryData, "application/pdf", "form.pdf")
End Function
The mobile client sends a dictionary of field names and values. The server fills them and returns a form the user can review, complete any remaining fields in a PDF viewer, and submit.
How Do You Extract Text and Merge PDFs from a Xamarin App?
Beyond generation, IronPDF supports a wide range of document operations you can expose as API endpoints:
- Extract text from PDF: Parse PDF content to index documents or prefill data entry forms.
- Merge or split PDFs: Combine multiple reports into a single PDF or split a large document into per-section files.
- Convert PDF to image: Render PDF pages as PNG or JPEG thumbnails for preview in the mobile UI.
Each of these becomes a separate API endpoint. The Xamarin client calls them like any other REST resource, keeping the mobile code free of PDF logic and the server as the authoritative document processor.
What Are the Common Issues and How Do You Fix Them?
The server-client architecture is straightforward, but several production concerns deserve attention:
| Issue | Cause | Recommended Fix |
|---|---|---|
| Request timeout | Complex HTML with many remote assets takes time to render | Increase HttpClient.Timeout and set server-side render timeout in rendering options |
| Large PDF memory spike | Streaming a 20 MB PDF through the response body | Upload to blob storage and return a short-lived download URL instead |
| Offline generation | Device has no connectivity when the user requests a PDF | Queue requests locally and retry when connectivity is restored |
| Unauthorized API access | Endpoint is open to the internet | Secure with JWT or API key; enforce HTTPS on all routes |
| Font not embedded | Server OS does not have the font installed | Embed the font in the HTML as a base64 data URI or as a CSS @font-face rule |
| iOS storage permission | App targets iOS 14+ with tighter sandboxing | Write to Environment.SpecialFolder.MyDocuments inside the app sandbox |
For rate limiting, add middleware on the ASP.NET Core side using a library such as AspNetCoreRateLimit. Log each generation request with timing data so you can spot slow templates before they affect users.
Should You Migrate from Xamarin to .NET MAUI?
If you are starting a new mobile project in 2026, .NET MAUI is the right choice. Microsoft ended Xamarin support in May 2024, meaning no further security patches or bug fixes. .NET MAUI is the direct successor and runs on .NET 10, matching the current IronPDF runtime.
The server-side architecture described in this guide works identically for .NET MAUI apps -- the client HTTP code is essentially the same; only the DependencyService is replaced by MAUI's built-in dependency injection. Teams maintaining existing Xamarin apps should plan a migration to MAUI; the official .NET MAUI migration guide from Microsoft documents the steps in detail.
How Do You Deploy and License IronPDF for Production?
Deployment is straightforward: containerize the ASP.NET Core API with Docker and push it to Azure App Service, AWS ECS, or any Kubernetes cluster. The IronPDF license key is set as an environment variable on the server:
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY")
?? throw new InvalidOperationException("IronPDF license key not set.");
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY")
?? throw new InvalidOperationException("IronPDF license key not set.");
Imports System
Imports IronPdf
IronPdf.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY"), Throw New InvalidOperationException("IronPDF license key not set."))
Review the IronPDF licensing page to select the right tier for your deployment. A free trial license lets you test the full feature set before committing. For containerized or serverless deployments, check that the license tier covers the number of server instances running simultaneously.
After licensing, explore the IronPDF documentation for advanced configuration options including thread-safe rendering settings, PDF/A compliance, and accessibility tagging.
Production Deployment Checklist
| Item | Recommendation |
|---|---|
| License key | Store in environment variables or a secret manager, never in source code |
| HTTPS | Enforce TLS on all API endpoints; never send HTML payloads over plain HTTP |
| Authentication | Use JWT bearer tokens or API keys; revoke on breach |
| Caching | Cache identical HTML payloads for a short TTL to reduce redundant renders |
| Scaling | IronPDF is thread-safe; run multiple API replicas behind a load balancer |
| Monitoring | Track render latency and error rates; alert on spikes above baseline |
The server-side pattern scales horizontally without any changes to the Xamarin or MAUI client. Add replicas as PDF generation volume grows and rely on the load balancer to distribute requests evenly.
Frequently Asked Questions
Can IronPDF be used natively in Xamarin.Forms?
IronPDF does not run natively in Xamarin.Forms, but it can be integrated using a server-side approach to handle PDF creation and manipulation.
What are the benefits of using IronPDF for PDF generation in mobile apps?
Using IronPDF allows you to create PDF files, fill forms, handle multiple pages, and include images, fonts, and custom layouts, enhancing the PDF generation capabilities of your mobile apps.
How does IronPDF handle PDF creation in Xamarin?
IronPDF uses a server-side approach to generate PDFs in Xamarin, enabling complex PDF functionalities that are not typically supported on mobile devices.
Is it possible to fill PDF forms using IronPDF in Xamarin?
Yes, IronPDF supports filling PDF forms as part of its comprehensive PDF handling features for Xamarin applications.
What challenges does IronPDF address in Xamarin PDF generation?
IronPDF addresses challenges such as errors and missing functionalities when generating PDFs directly on mobile devices by using a server-side solution.
Can IronPDF handle custom layouts in PDFs for Xamarin apps?
Yes, IronPDF can include custom layouts in generated PDFs, giving you control over the design and presentation of your documents.
What kind of PDF features can be implemented in Xamarin using IronPDF?
IronPDF allows implementation of features like multi-page documents, form filling, image and font incorporation, and custom layouts in Xamarin.
Why is a server-side approach recommended for PDF generation in Xamarin with IronPDF?
A server-side approach is recommended because it bypasses the limitations of mobile devices, ensuring reliable PDF creation and advanced features.




