typed-xlsx
Columns

Hyperlinks

Add native Excel hyperlinks without changing the rendered cell value.

Use hyperlink when a cell should keep its normal value but also carry native Excel hyperlink metadata.

The cell value still comes from accessor, transform, or formula. The hyperlink target is separate.

kitchen-sink.xlsxOpen in playground
1
2
3
4
5
6
7
External, Email, and Internal Hyperlinks
Customer Record
Email
Internal Jump
Acme Manufacturing
ops@acme.example
INV-1001
Bluebird Health
finance@bluebird.example
INV-1002
Cinder Labs
team@cinder.example
INV-1003
07 Hyperlinks
External, mailto and in-workbook links from the kitchen-sink example.

Basic usage

import { 
createExcelSchema
} from "typed-xlsx";
type
Row
= {
customerId
: string;
customerName
: string;
hasPortal
: boolean;
}; const
schema
=
createExcelSchema
<
Row
>()
.
column
("customerName", {
accessor
: "customerName",
hyperlink
: ({
row
}) =>
row
.hasPortal
? {
target
: `https://example.com/customers/${
row
.
customerId
}`,
tooltip
: "Open customer record",
} : null, }) .
build
();

Supported forms:

  • hyperlink: "https://example.com/..."
  • hyperlink: { target, tooltip?, style? }
  • hyperlink: ({ row, rowIndex, subRowIndex, ctx }) => string | { target, tooltip?, style? } | null | undefined

Returning null or undefined means that specific cell has no hyperlink.

tooltip can be a string or a lazy callback, so shared schemas can resolve localized tooltip text when rows are planned.

Linked cells get a default hyperlink appearance:

  • blue text
  • underline

If you need a different look, put it directly on the hyperlink object:

import { 
createExcelSchema
} from "typed-xlsx";
const
schema
=
createExcelSchema
<{
customerId
: string;
customerName
: string;
hasPortal
: boolean;
}>() .
column
("customerName", {
accessor
: "customerName",
hyperlink
: ({
row
}) =>
row
.hasPortal
? {
target
: `https://example.com/customers/${
row
.
customerId
}`,
tooltip
: "Open customer record",
style
: {
font
: {
color
: {
rgb
: "7C3AED" },
underline
: false,
bold
: true,
}, }, } : null, }) .
build
();

That style only applies when the link exists.

External links use worksheet relationships:

hyperlink: () => ({ 
target
: "https://example.com/report/123" });

Internal workbook links use Excel locations:

hyperlink: () => ({ 
target
: "#'Summary'!A1",
tooltip
: "Jump to summary" });

Notes

  • hyperlinks are independent from the rendered cell value
  • hyperlink targets are concrete strings at export time
  • formula-based hyperlink targets are intentionally not supported
  • hyperlink-local style is ignored when the callback returns null or undefined
Copyright © 2026 Cyprien Thao. Released under the MIT License.