How to Add Custom Hyphenation to PDF Generation in C#
Custom hyphenation in C# PDF generation helps fix awkward spacing, word overflow, and poor text wrapping in narrow columns, invoices, contracts, and multilingual reports. When a PDF renderer does not apply the correct hyphenation patterns, justified text can leave large gaps or break poorly across lines.
In IronPDF, hyphenation is handled during HTML-to-PDF rendering through the Chromium engine, not through a Word-style document object model. The CSS hyphens: auto property allows the renderer to break words at valid syllable boundaries, and IronPDF applies that behavior during PDF generation. The CustomHyphenation property in ChromePdfRenderOptions controls which hyphenation patterns are used.
Pattern files use the TeX format and can be loaded from either a local file path or a remote URL. This makes it possible to define custom hyphenation rules for different languages and document layouts with more control over word breaks in the final PDF.
This guide explains how to use the CustomHyphenationDefinitions API in C#, including local and remote pattern loading, fallback behavior, limitations, error handling, and caching.
Quickstart
-
Install IronPDF with NuGet Package Manager
PM > Install-Package IronPdf -
Copy and run this code snippet.
using IronPdf; // Create renderer and assign custom hyphenation patterns from a remote URL var renderer = new ChromePdfRenderer(); renderer.RenderingOptions.CustomHyphenation = new CustomHyphenationDefinitions { PatternSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.pat.txt", ExceptionSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.hyp.txt" }; // Render HTML with CSS hyphens:auto to trigger word breaking var pdf = renderer.RenderHtmlAsPdf("<div style='text-align:justify; hyphens:auto; width:120px;'>Supercalifragilisticexpialidocious</div>"); pdf.SaveAs("hyphenated.pdf"); -
Deploy to test on your live environment
Start using IronPDF in your project today with a free trial
Minimal Workflow
- Install the IronPDF NuGet package
- Create a
ChromePdfRendererinstance - Set
RenderingOptions.CustomHyphenationto a newCustomHyphenationDefinitionswith aPatternSourcepath or URL - Include
hyphens: autoin the HTML content's CSS - Call
RenderHtmlAsPdfand save the result
How Does Custom Hyphenation Work in PDF Rendering?
The CustomHyphenationDefinitions class defines where IronPDF loads hyphenation rules from during the rendering process. The Chromium engine reads these patterns and applies them when the CSS hyphens: auto rule is present on an HTML element.
What Is the CustomHyphenationDefinitions Class?
The class exposes two properties:
| Property | Type | Required | Description |
|---|---|---|---|
PatternSource | string | Yes | Path or URL to the hyphenation patterns file (e.g., hyph-en-us.pat.txt) |
ExceptionSource | string | No | Path or URL to the hyphenation exceptions file (e.g., hyph-en-us.hyp.txt) |
Pattern files follow the TeX hyphenation format maintained by the tex-hyphen project on GitHub. Each language has two files in the repository: hyph-{lang}.pat.txt for pattern rules and hyph-{lang}.hyp.txt for the exception list. When referencing files hosted on GitHub, the raw content URL (starting with https://raw.githubusercontent.com/) is required — a standard GitHub page URL returns HTML, not the pattern text.
How Does Custom Hyphenation Override the Built-In Language Setting?
The HyphenationLanguage enum on ChromePdfRenderOptions provides built-in presets for English (US), English (British), and Russian. The CustomHyphenation property takes precedence over this enum when both are set, following a clear priority chain:
- CustomHyphenation — if set with a valid PatternSource, custom patterns are used
- HyphenationLanguage — if no custom patterns are configured, the built-in language preset applies
- None — if neither is set, no hyphenation occurs
What Happens When Custom Pattern Loading Fails?
Errors during pattern loading are logged but do not throw exceptions. The render operation continues without hyphenation rather than failing. If a HyphenationLanguage value is also configured, the renderer falls back to that built-in preset.
This silent-failure behavior is a deliberate design choice for production environments. A network timeout fetching a remote pattern file, an invalid file path, a DNS resolution failure, or malformed pattern content will not crash the rendering pipeline. The PDF still generates — it just lacks hyphenated word breaks.
The trade-off is visibility. A bad pattern file or unreachable URL on the first load will silently affect every subsequent render using those same source values (since caching stores the failure state too). The recommendation is to validate pattern files and confirm network access to remote URLs during application startup or CI/CD deployment checks — not at render time.
How Can Pattern Files Be Loaded from a Remote URL?
Pointing PatternSource at a remote URL is the fastest way to apply custom hyphenation without bundling files into the project. The following example loads U.S. English patterns from the tex-hyphen repository and renders a justified text block:
using IronPdf;
var renderer = new ChromePdfRenderer();
// Load custom patterns from a remote TeX hyphenation repository
renderer.RenderingOptions.CustomHyphenation = new CustomHyphenationDefinitions
{
PatternSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.pat.txt",
ExceptionSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.hyp.txt"
};
string html = @"
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.narrow-column {
width: 150px;
text-align: justify;
hyphens: auto;
-webkit-hyphens: auto;
border: 1px solid #ccc;
padding: 10px;
}
</style>
</head>
<body>
<div class='narrow-column'>
The extraordinarily sophisticated implementation demonstrates
how hyphenation significantly improves the typographical quality
of justified text in constrained column widths.
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("remote-hyphenation.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
// Load custom patterns from a remote TeX hyphenation repository
renderer.RenderingOptions.CustomHyphenation = new CustomHyphenationDefinitions
{
PatternSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.pat.txt",
ExceptionSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.hyp.txt"
};
string html = @"
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.narrow-column {
width: 150px;
text-align: justify;
hyphens: auto;
-webkit-hyphens: auto;
border: 1px solid #ccc;
padding: 10px;
}
</style>
</head>
<body>
<div class='narrow-column'>
The extraordinarily sophisticated implementation demonstrates
how hyphenation significantly improves the typographical quality
of justified text in constrained column widths.
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("remote-hyphenation.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
' Load custom patterns from a remote TeX hyphenation repository
renderer.RenderingOptions.CustomHyphenation = New CustomHyphenationDefinitions With {
.PatternSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.pat.txt",
.ExceptionSource = "https://raw.githubusercontent.com/hyphenation/tex-hyphen/master/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/hyph-en-us.hyp.txt"
}
Dim html As String = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.narrow-column {
width: 150px;
text-align: justify;
hyphens: auto;
-webkit-hyphens: auto;
border: 1px solid #ccc;
padding: 10px;
}
</style>
</head>
<body>
<div class='narrow-column'>
The extraordinarily sophisticated implementation demonstrates
how hyphenation significantly improves the typographical quality
of justified text in constrained column widths.
</div>
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("remote-hyphenation.pdf")
Output
The rendered PDF shows the justified paragraph with clean word breaks at syllable boundaries. Without hyphenation, this same text would produce large inter-word gaps or overflow the column.
Both hyphens: auto and -webkit-hyphens: auto CSS declarations are needed for Chromium compatibility. The text-align: justify rule makes hyphenation most visible. If neither CSS declaration is present on the target HTML elements, the custom patterns are loaded but never applied.
https://github.com/hyphenation/tex-hyphen/blob/master/... returns an HTML page wrapper, which will fail pattern validation. Use the https://raw.githubusercontent.com/... form, or click the "Raw" button on GitHub to obtain the correct URL.What Are the Remote Source Constraints?
| Constraint | Value |
|---|---|
| Protocols | HTTP and HTTPS (HTTPS recommended) |
| Allowed content types | text/plain, application/octet-stream |
| Maximum response size | 5 MB |
| Request timeout | 10 seconds |
| Security | Requests to private/local IPs (10.x.x.x, 192.168.x.x, localhost) are blocked to prevent SSRF attacks |
| Rejected content | Binary files, files with null bytes, files containing <script> tags |
Containers and cloud environments (Docker, Azure, AWS) must have outbound HTTPS access to the pattern file host for remote loading to succeed.
How Can Pattern Files Be Loaded from Local Files?
For environments where external network access is restricted or where build-time bundling is preferred, PatternSource also accepts a local file system path:
hyph-en-us.pat.txt and hyph-en-us.hyp.txt from the tex-hyphen repository and place them in the path referenced by your code.using IronPdf;
var renderer = new ChromePdfRenderer();
// Load English hyphenation patterns from local files
renderer.RenderingOptions.CustomHyphenation = new CustomHyphenationDefinitions
{
PatternSource = @"C:\patterns\hyph-en-us.pat.txt",
ExceptionSource = @"C:\patterns\hyph-en-us.hyp.txt"
};
string html = @"
<html>
<head>
<style>
.invoice-container {
width: 220px;
text-align: justify;
hyphens: auto;
-webkit-hyphens: auto;
font-family: Georgia, serif;
font-size: 11px;
line-height: 1.5;
border: 1px solid #ddd;
padding: 12px;
}
h3 { font-size: 13px; margin-top: 0; }
.terms { color: #555; margin-top: 10px; font-size: 9px; }
</style>
</head>
<body>
<div class='invoice-container'>
<h3>Invoice #20260331</h3>
<p>Nondiscrimination acknowledgement: The undersigned
representative hereby confirms that all pharmaceutical
reimbursement documentation has been independently
verified and cross-referenced against the applicable
regulatory framework established by the appropriate
governmental oversight authority.</p>
<p class='terms'>Notwithstanding any indemnification
provisions, the counterparty's disproportionate
liability shall not exceed the predetermined
recharacterization threshold established under the
intergovernmental cooperation agreement.</p>
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("local-hyphenation.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
// Load English hyphenation patterns from local files
renderer.RenderingOptions.CustomHyphenation = new CustomHyphenationDefinitions
{
PatternSource = @"C:\patterns\hyph-en-us.pat.txt",
ExceptionSource = @"C:\patterns\hyph-en-us.hyp.txt"
};
string html = @"
<html>
<head>
<style>
.invoice-container {
width: 220px;
text-align: justify;
hyphens: auto;
-webkit-hyphens: auto;
font-family: Georgia, serif;
font-size: 11px;
line-height: 1.5;
border: 1px solid #ddd;
padding: 12px;
}
h3 { font-size: 13px; margin-top: 0; }
.terms { color: #555; margin-top: 10px; font-size: 9px; }
</style>
</head>
<body>
<div class='invoice-container'>
<h3>Invoice #20260331</h3>
<p>Nondiscrimination acknowledgement: The undersigned
representative hereby confirms that all pharmaceutical
reimbursement documentation has been independently
verified and cross-referenced against the applicable
regulatory framework established by the appropriate
governmental oversight authority.</p>
<p class='terms'>Notwithstanding any indemnification
provisions, the counterparty's disproportionate
liability shall not exceed the predetermined
recharacterization threshold established under the
intergovernmental cooperation agreement.</p>
</div>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("local-hyphenation.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
' Load English hyphenation patterns from local files
renderer.RenderingOptions.CustomHyphenation = New CustomHyphenationDefinitions With {
.PatternSource = "C:\patterns\hyph-en-us.pat.txt",
.ExceptionSource = "C:\patterns\hyph-en-us.hyp.txt"
}
Dim html As String = "
<html>
<head>
<style>
.invoice-container {
width: 220px;
text-align: justify;
hyphens: auto;
-webkit-hyphens: auto;
font-family: Georgia, serif;
font-size: 11px;
line-height: 1.5;
border: 1px solid #ddd;
padding: 12px;
}
h3 { font-size: 13px; margin-top: 0; }
.terms { color: #555; margin-top: 10px; font-size: 9px; }
</style>
</head>
<body>
<div class='invoice-container'>
<h3>Invoice #20260331</h3>
<p>Nondiscrimination acknowledgement: The undersigned
representative hereby confirms that all pharmaceutical
reimbursement documentation has been independently
verified and cross-referenced against the applicable
regulatory framework established by the appropriate
governmental oversight authority.</p>
<p class='terms'>Notwithstanding any indemnification
provisions, the counterparty's disproportionate
liability shall not exceed the predetermined
recharacterization threshold established under the
intergovernmental cooperation agreement.</p>
</div>
</body>
</html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("local-hyphenation.pdf")
Output
As can be seen below, long words that would otherwise overflow or create excessive spacing are broken at syllable boundaries automatically. The engine only hyphenates where needed — words that fit cleanly on a line are left whole.
Switching to another language requires only a change to the file paths:
// Switch to French hyphenation — just change the file paths
renderer.RenderingOptions.CustomHyphenation = new CustomHyphenationDefinitions
{
PatternSource = @"C:\patterns\hyph-fr.pat.txt",
ExceptionSource = @"C:\patterns\hyph-fr.hyp.txt"
};
// Switch to French hyphenation — just change the file paths
renderer.RenderingOptions.CustomHyphenation = new CustomHyphenationDefinitions
{
PatternSource = @"C:\patterns\hyph-fr.pat.txt",
ExceptionSource = @"C:\patterns\hyph-fr.hyp.txt"
};
' Switch to French hyphenation — just change the file paths
renderer.RenderingOptions.CustomHyphenation = New CustomHyphenationDefinitions With {
.PatternSource = "C:\patterns\hyph-fr.pat.txt",
.ExceptionSource = "C:\patterns\hyph-fr.hyp.txt"
}
This makes CustomHyphenation particularly useful for languages not covered by the built-in PdfHyphenationLanguage enum, which currently supports only English (US), English (British), and Russian.
What Are the Local File Constraints?
| Constraint | Value |
|---|---|
| Allowed extensions | .txt, .pat |
| Maximum file size | 5 MB |
| Encoding | UTF-8 |
| Content rules | Valid hyphenation patterns only — no comments, metadata, headers, TeX directives, or encoding notes |
| Rejected content | Binary files, files with null bytes, files containing <script> tags |
How Does Caching Affect Performance in Batch Rendering?
Custom hyphenation patterns are cached in memory after the first load, keyed by the PatternSource and ExceptionSource values. Subsequent renders that reference the same source paths or URLs reuse the cached patterns without re-downloading or re-reading the files.
This behavior has two practical implications for high-volume PDF rendering workflows:
Performance: The first render incurs the I/O cost (network request or disk read). Every render after that is effectively free from a pattern-loading perspective. For batch jobs generating hundreds of PDFs with the same hyphenation configuration, the overhead is negligible.
Silent failure persistence: Because errors during pattern loading do not throw exceptions and the renderer continues without hyphenation, a bad pattern file or network failure on the first load will silently persist across the entire batch. Every subsequent render will also lack hyphenation, with no additional error signal. Validate pattern files and confirm URL accessibility during application startup or deployment — not at render time.
Cache key identity: The cache key is the exact string value of PatternSource (and ExceptionSource if set). Two renderer instances pointing to the same URL or file path share the same cached patterns. Changing the URL — even to a different version of the same file — forces a fresh load.
Pre-validate file content before production deployment. Pattern files must contain only valid hyphenation text. Presence of comments, TeX directives, encoding declarations, or any non-pattern content causes the integration to fail. The tex-hyphen repository provides pre-built clean pattern files for dozens of languages.
HTTPS is recommended for remote pattern sources. HTTP is supported but offers no transport-layer protection for the file content.
What Are the Next Steps?
The CustomHyphenation property on ChromePdfRenderOptions gives direct control over word-breaking behavior for any language supported by a TeX pattern file — extending beyond the three built-in presets available through PdfHyphenationLanguage. Pattern files load from remote URLs or local paths, are cached in memory after first use, and fall back to the HyphenationLanguage setting if loading fails. Errors are logged but never thrown, so pattern validation should happen during deployment rather than at render time.
For related IronPDF rendering configuration, see:
ChromePdfRenderOptionsAPI reference for all available rendering optionsPdfHyphenationLanguageenum for the built-in language presets- HTML to PDF rendering tutorial for the full HTML rendering pipeline
- Rendering options how-to for other ChromePdfRenderOptions configuration
- IronPDF features overview for the full set of PDF generation and manipulation capabilities
Get a free 30-day trial of IronPDF to test custom hyphenation in a live project, or view licensing options for production deployment.

