How-to guides/Annotations

Add URL links and internal links to a PDF in Rust

Create clickable link annotations that open URLs or jump to other pages within the same document.

rust
use pdfluent::{Document, Rect, annotation::{LinkAnnotation, LinkTarget}};

fn main() -> pdfluent::Result<()> {
    let mut doc = Document::open("input.pdf")?;

    // Add a URL link on the first page
    let rect = Rect::new(72.0, 700.0, 250.0, 720.0);
    let link = LinkAnnotation::url(rect, "https://pdfluent.com");
    doc.page_mut(0)?.add_annotation(link);

    doc.save("with_links.pdf")?;
    Ok(())
}
Install:cargo add pdfluentDownload SDK →

Step by step

1

Open the document for modification

Annotations are stored per-page. Open the file with a mutable Document.

rust
let mut doc = Document::open("input.pdf")?;
2

Define the click rectangle

A link annotation needs a bounding box (the clickable area) in page coordinates (points, origin at bottom-left).

rust
use pdfluent::Rect;

// Clickable area: x1=72, y1=700, x2=250, y2=720
let rect = Rect::new(72.0, 700.0, 250.0, 720.0);
3

Create a URL link annotation

LinkAnnotation::url builds a URI action annotation. The URL must be a valid absolute URI.

rust
use pdfluent::annotation::{LinkAnnotation, LinkBorder};

let link = LinkAnnotation::url(rect, "https://example.com")
    .border(LinkBorder::none());  // hide the default blue border
4

Create an internal page-destination link

Use LinkTarget::Page to link to a specific page number within the same document. Page numbers are zero-based.

rust
use pdfluent::annotation::LinkTarget;

let dest_rect = Rect::new(72.0, 600.0, 300.0, 620.0);
let internal_link = LinkAnnotation::destination(
    dest_rect,
    LinkTarget::page(4, None), // jump to page 5 (0-indexed = 4)
);
5

Add the annotations to the page and save

Call add_annotation for each link. Multiple annotations can be added to the same page.

rust
let page = doc.page_mut(0)?;
page.add_annotation(link);
page.add_annotation(internal_link);

doc.save("with_links.pdf")?;

Notes and tips

  • PDF link annotations do not style the text visually. You need to draw underline and color separately in the content stream.
  • Use LinkBorder::none() to hide the default blue rectangle that viewers draw around links.
  • Named destinations are more stable than page-number destinations when pages might be inserted or removed later.
  • URI links must be full absolute URLs. Relative URLs are not part of the PDF URI action specification.

Why PDFluent for this

Pure Rust

No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.

Memory safe

Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.

Runs anywhere

Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.

Frequently asked questions