Clickable links
Render the URLs, email addresses, and phone numbers in your cell values as clickable links, without changing the data.
Overview
By default, a cell value such as https://handsontable.com renders as plain text. With the autoLink option, Handsontable finds the URLs in the text a cell renders and wraps each one in a link element. The cell keeps its own renderer, and the value stays unchanged, so copying, autofill, sorting, filtering, and export work as before.
Handsontable links the http, https, mailto, and tel schemes only. Any other scheme, javascript: included, stays plain text.
Enable automatic links
Set the autoLink option to true:
import { HotTable } from '@handsontable/react-wrapper';import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modulesregisterAllModules();
const ExampleComponent = () => { return ( <HotTable data={[ [ 'Update API docs', 'Ana García', 'https://tracker.example.com/tasks/4821', 'mailto:ana.garcia@example.com', 'Draft at https://wiki.example.com/api-docs, review by Friday.', ], [ 'Deploy hotfix', 'James Okafor', 'https://tracker.example.com/tasks/4830', 'mailto:james.okafor@example.com', 'Rollback plan: https://wiki.example.com/rollback', ], [ 'Migrate CI runners', 'Li Wei', 'https://tracker.example.com/tasks/4835', 'tel:+48123456789', 'Blocked on vendor call.', ], [ 'Renew TLS certificates', 'Priya Nair', 'https://tracker.example.com/tasks/4841', 'mailto:priya.nair@example.com', 'See https://wiki.example.com/tls for the checklist.', ], [ 'Audit access logs', 'Tomás Rivera', 'https://tracker.example.com/tasks/4846', 'tel:+48987654321', 'Report due 2025-06-30.', ], ]} colHeaders={['Task', 'Owner', 'Tracker', 'Contact', 'Notes']} colWidths={[180, 120, 260, 220, 320]} height="auto" autoLink={true} autoWrapRow={true} autoWrapCol={true} licenseKey="non-commercial-and-evaluation" /> );};
export default ExampleComponent;import { HotTable } from '@handsontable/react-wrapper';import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modulesregisterAllModules();
const ExampleComponent = () => { return ( <HotTable data={[ ['Update API docs', 'Ana García', 'https://tracker.example.com/tasks/4821', 'mailto:ana.garcia@example.com', 'Draft at https://wiki.example.com/api-docs, review by Friday.'], ['Deploy hotfix', 'James Okafor', 'https://tracker.example.com/tasks/4830', 'mailto:james.okafor@example.com', 'Rollback plan: https://wiki.example.com/rollback'], ['Migrate CI runners', 'Li Wei', 'https://tracker.example.com/tasks/4835', 'tel:+48123456789', 'Blocked on vendor call.'], ['Renew TLS certificates', 'Priya Nair', 'https://tracker.example.com/tasks/4841', 'mailto:priya.nair@example.com', 'See https://wiki.example.com/tls for the checklist.'], ['Audit access logs', 'Tomás Rivera', 'https://tracker.example.com/tasks/4846', 'tel:+48987654321', 'Report due 2025-06-30.'], ]} colHeaders={['Task', 'Owner', 'Tracker', 'Contact', 'Notes']} colWidths={[180, 120, 260, 220, 320]} height="auto" autoLink={true} autoWrapRow={true} autoWrapCol={true} licenseKey="non-commercial-and-evaluation" /> );};
export default ExampleComponent;A URL inside longer text becomes a link as well. Punctuation that wraps a URL in a sentence, such as a trailing period or a closing parenthesis, stays outside the link.
Configure the links
Set autoLink to an object to configure the links:
| Option | Default | Description |
|---|---|---|
target | '_blank' | Where the links open: a new tab ('_blank') or the current one ('_self'). |
schemes | all four | The URL schemes to link, a subset of 'http', 'https', 'mailto', and 'tel'. A column or cell schemes can only narrow this fixed four-scheme allowlist, never widen it, and replaces the grid-level list for those cells. |
inline | true | true links URLs inside longer text. false links only a cell whose whole value is one URL. |
strict | true | true links only URLs that carry a scheme. false also links bare domains and bare email addresses. See Link bare domains and email addresses. |
className | '' | Extra class name(s) added to every link element. |
The plugin is enabled at the grid level. To opt a column or a cell out, set autoLink: false in the columns, cells, or cell option. To override the settings for a column or a cell, set an object there:
import { HotTable } from '@handsontable/react-wrapper';import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modulesregisterAllModules();
const ExampleComponent = () => { return ( <HotTable data={[ [ 'Update API docs', 'https://tracker.example.com/tasks/4821', 'mailto:ana.garcia@example.com', 'Draft at https://wiki.example.com/api-docs', ], [ 'Deploy hotfix', 'https://tracker.example.com/tasks/4830', 'mailto:james.okafor@example.com', 'Rollback plan: https://wiki.example.com/rollback', ], ['Migrate CI runners', 'https://tracker.example.com/tasks/4835', 'tel:+48123456789', 'Blocked on vendor call.'], [ 'Renew TLS certificates', 'https://tracker.example.com/tasks/4841', 'mailto:priya.nair@example.com', 'See https://wiki.example.com/tls', ], ['Audit access logs', 'https://tracker.example.com/tasks/4846', 'tel:+48987654321', 'Report due 2025-06-30.'], ]} colHeaders={['Task', 'Tracker', 'Contact', 'Notes']} colWidths={[180, 260, 220, 320]} height="auto" // Open links in the same tab, link web URLs only, and add a class to every link. autoLink={{ target: '_self', schemes: ['http', 'https'], className: 'tracker-link', }} columns={[ {}, // Link only a cell whose whole value is a URL. { autoLink: { inline: false } }, // Keep the contact column as plain text. { autoLink: false }, {}, ]} autoWrapRow={true} autoWrapCol={true} licenseKey="non-commercial-and-evaluation" /> );};
export default ExampleComponent;import { HotTable } from '@handsontable/react-wrapper';import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modulesregisterAllModules();
const ExampleComponent = () => { return ( <HotTable data={[ ['Update API docs', 'https://tracker.example.com/tasks/4821', 'mailto:ana.garcia@example.com', 'Draft at https://wiki.example.com/api-docs'], ['Deploy hotfix', 'https://tracker.example.com/tasks/4830', 'mailto:james.okafor@example.com', 'Rollback plan: https://wiki.example.com/rollback'], ['Migrate CI runners', 'https://tracker.example.com/tasks/4835', 'tel:+48123456789', 'Blocked on vendor call.'], ['Renew TLS certificates', 'https://tracker.example.com/tasks/4841', 'mailto:priya.nair@example.com', 'See https://wiki.example.com/tls'], ['Audit access logs', 'https://tracker.example.com/tasks/4846', 'tel:+48987654321', 'Report due 2025-06-30.'], ]} colHeaders={['Task', 'Tracker', 'Contact', 'Notes']} colWidths={[180, 260, 220, 320]} height="auto" // Open links in the same tab, link web URLs only, and add a class to every link. autoLink={{ target: '_self', schemes: ['http', 'https'], className: 'tracker-link', }} columns={[ {}, // Link only a cell whose whole value is a URL. { autoLink: { inline: false } }, // Keep the contact column as plain text. { autoLink: false }, {}, ]} autoWrapRow={true} autoWrapCol={true} licenseKey="non-commercial-and-evaluation" /> );};
export default ExampleComponent;Link bare domains and email addresses
Keep autoLink’s strict option at its default, true, unless your data is known to hold bare domains or email addresses. Set it to false only for that data, as an opt-in — not as a general upgrade to the rest of your grid.
By default (strict: true), autoLink links only a value that already carries a scheme, such as https://handsontable.com or mailto:jane@example.com. Set strict to false to also link a bare domain, such as handsontable.com, as an https URL, and a bare email address, such as jane@example.com, as a mailto URL:
autoLink: { strict: false,},A bare domain’s top-level domain (the .com in handsontable.com) is validated against the IANA top-level domain list, bundled with Handsontable at build time. Handsontable makes no network request to validate a bare domain, so strict: false works the same in an air-gapped environment as it does anywhere else. A punycode top-level domain (xn--...) is never linked; every other IANA top-level domain is used as-is.
Keyboard access
A link inside a cell stays out of the tab order, so tabbing still moves between cells. To open the first link of the selected cell, press Alt+Enter. The link opens where target says.
Inline mode can link several URLs inside one cell. Alt+Enter always opens the first one; reach the others with the mouse. This is a deliberate limitation.
Styling
Each link element gets the ht-link and ht-auto-link classes, and takes its color from the --ht-link-color and --ht-link-hover-color theme variables. Add your own class through the className option.
A mailto: or tel: link hides its scheme prefix from view. The prefix stays in the DOM inside a ht-link-scheme element, so the cell shows only the address or the number - restyle it through that class if you need the prefix visible.
Links from formulas
A cell whose formula is HYPERLINK() can render as a link through the hyperlinks property of the formulas option. Read more in Render HYPERLINK formulas as links. When both features are on, a HYPERLINK cell renders the formula’s link and autoLink leaves it alone.
Security
Handsontable builds every link element through the DOM and checks the parsed URL scheme against a fixed allowlist, so a value such as javascript:alert(1) never becomes a link. Every link carries rel="noopener noreferrer". The schemes option can narrow the allowlist, never widen it.
Related API reference
Configuration options
Plugins