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.


NuGet Install with NuGet

PM >  Install-Package IronPdf

Check out IronPDF on NuGet for quick installation. With over 10 million downloads, it’s transforming PDF development with C#. You can also download the DLL or Windows installer.

Quickstart

  1. Install IronPDF with NuGet Package Manager

    PM > Install-Package IronPdf
  2. 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");
  3. Deploy to test on your live environment

    Start using IronPDF in your project today with a free trial

    arrow pointer

Minimal Workflow

  1. Install the IronPDF NuGet package
  2. Create a ChromePdfRenderer instance
  3. Set RenderingOptions.CustomHyphenation to a new CustomHyphenationDefinitions with a PatternSource path or URL
  4. Include hyphens: auto in the HTML content's CSS
  5. Call RenderHtmlAsPdf and 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:

Table 1: CustomHyphenationDefinitions Properties
PropertyTypeRequiredDescription
PatternSourcestringYesPath or URL to the hyphenation patterns file (e.g., hyph-en-us.pat.txt)
ExceptionSourcestringNoPath 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:

  1. CustomHyphenation — if set with a valid PatternSource, custom patterns are used
  2. HyphenationLanguage — if no custom patterns are configured, the built-in language preset applies
  3. 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")
$vbLabelText   $csharpLabel

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.

Please noteThe URL must point to raw text content. A standard GitHub URL like 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?

Table 2: Remote URL Constraints
ConstraintValue
ProtocolsHTTP and HTTPS (HTTPS recommended)
Allowed content typestext/plain, application/octet-stream
Maximum response size5 MB
Request timeout10 seconds
SecurityRequests to private/local IPs (10.x.x.x, 192.168.x.x, localhost) are blocked to prevent SSRF attacks
Rejected contentBinary 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:

Please noteThe pattern files must exist on disk before running. Download 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")
$vbLabelText   $csharpLabel

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"
}
$vbLabelText   $csharpLabel

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?

Table 3: Local File Constraints
ConstraintValue
Allowed extensions.txt, .pat
Maximum file size5 MB
EncodingUTF-8
Content rulesValid hyphenation patterns only — no comments, metadata, headers, TeX directives, or encoding notes
Rejected contentBinary 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:

Get a free 30-day trial of IronPDF to test custom hyphenation in a live project, or view licensing options for production deployment.

Ahmad Sohail
Full Stack Developer

Ahmad is a full-stack developer with a strong foundation in C#, Python, and web technologies. He has a deep interest in building scalable software solutions and enjoys exploring how design and functionality meet in real-world applications.

Before joining the Iron Software team, Ahmad worked on automation projects ...

Read More
Ready to Get Started?
Nuget Downloads 18,120,209 | Version: 2026.4 just released
Still Scrolling Icon

Still Scrolling?

Want proof fast? PM > Install-Package IronPdf
run a sample watch your HTML become a PDF.