Overview
The link widget creates clickable hyperlinks that can open URLs in terminal emulators that support hyperlink escape codes (OSC 8). Links also support local press handlers for in-app navigation.
Basic Usage
import { ui } from "@rezi-ui/core";
// Simple link with URL
ui.link("https://rezi.dev");
// Link with custom label
ui.link("https://rezi.dev", "Visit Rezi Docs");
// Full props object
ui.link({
url: "https://github.com/rezi-ui/rezi",
label: "View on GitHub",
onPress: () => console.log("Link pressed"),
});
Props
URL to open in terminal hyperlink-capable renderers.
Link label text. Defaults to the URL if omitted.
Optional unique identifier for focus routing.
Optional local press handler. Called when link is activated via keyboard or mouse.
Disabled links are rendered but not focusable or pressable.
Opt out of Tab focus order while keeping id-based routing available.
Optional semantic label used for accessibility and debug announcements.
Optional text style for the link (color, bold, underline, etc.).
External Links
import { ui } from "@rezi-ui/core";
// Documentation link
ui.link("https://rezi.dev/docs", "Read the Docs");
// Repository link
ui.link("https://github.com/rezi-ui/rezi", "GitHub");
// Issue tracker
ui.link("https://github.com/rezi-ui/rezi/issues", "Report an Issue");
Email Links
import { ui } from "@rezi-ui/core";
ui.link("mailto:[email protected]", "Contact Support");
ui.link("mailto:[email protected]?subject=Hello&body=Hi Alice!", "Email Alice");
Local Navigation
Use onPress for in-app navigation:
import { ui } from "@rezi-ui/core";
ui.link({
url: "/settings",
label: "Settings",
onPress: () => app.router.navigate("/settings"),
});
ui.link({
url: "/profile",
label: "View Profile",
onPress: () => {
app.update({ currentView: "profile" });
},
});
Custom Styling
import { ui } from "@rezi-ui/core";
// Blue underlined link
ui.link({
url: "https://example.com",
label: "Example",
style: {
fg: { r: 70, g: 130, b: 255 },
underline: true,
},
});
// Bold link
ui.link({
url: "https://important.com",
label: "Important Link",
style: {
bold: true,
fg: { r: 255, g: 100, b: 100 },
},
});
Disabled Links
import { ui } from "@rezi-ui/core";
ui.link({
url: "https://unavailable.com",
label: "Unavailable",
disabled: true,
style: { dim: true },
});
Link Lists
import { ui } from "@rezi-ui/core";
const links = [
{ url: "https://rezi.dev", label: "Home" },
{ url: "https://rezi.dev/docs", label: "Documentation" },
{ url: "https://rezi.dev/examples", label: "Examples" },
{ url: "https://github.com/rezi-ui/rezi", label: "GitHub" },
];
ui.column(
{ gap: 0 },
links.map((link, index) =>
ui.row(
{ key: `link-${index}`, gap: 1 },
[ui.text("•"), ui.link(link.url, link.label)]
)
)
);
With Icons
import { ui } from "@rezi-ui/core";
ui.row({ gap: 1, items: "center" }, [
ui.icon("link"),
ui.link("https://rezi.dev", "Official Website"),
]);
ui.row({ gap: 1, items: "center" }, [
ui.icon("github"),
ui.link("https://github.com/rezi-ui/rezi", "Source Code"),
]);
import { ui } from "@rezi-ui/core";
ui.statusBar({
left: [ui.text("Rezi TUI Framework v1.0.0")],
right: [
ui.link("https://rezi.dev/docs", "Docs"),
ui.text("·"),
ui.link("https://github.com/rezi-ui/rezi", "GitHub"),
ui.text("·"),
ui.link("https://rezi.dev/support", "Support"),
],
});
Error Message Links
import { ui } from "@rezi-ui/core";
ui.callout(
"An error occurred. Check the logs for details.",
{
variant: "error",
}
);
ui.row({ gap: 1 }, [
ui.text("Need help?"),
ui.link("https://rezi.dev/troubleshooting", "Troubleshooting Guide"),
]);
Keyboard Navigation
Links support standard keyboard interaction:
| Key | Action |
|---|
Tab | Move to next focusable element |
Shift+Tab | Move to previous focusable element |
Enter | Activate link (open URL or call onPress) |
Space | Activate link (open URL or call onPress) |
Terminal Support
Link rendering depends on terminal capabilities:
- Supported terminals: iTerm2, Windows Terminal, Alacritty, kitty, GNOME Terminal
- Unsupported terminals: Links render as plain text with the label
- Detection: Rezi automatically detects terminal hyperlink support
Best Practices
- Provide descriptive labels - “View Documentation” is better than “Click here”
- Use consistent styling - Keep link colors and underlines uniform
- Test terminal support - Not all terminals render hyperlinks
- Combine with icons - Visual indicators improve scannability
- Disable unavailable links - Use
disabled prop instead of removing links
Examples
Help Panel
import { ui } from "@rezi-ui/core";
ui.panel("Help & Resources", [
ui.column({ gap: 1 }, [
ui.text("Documentation", { variant: "heading" }),
ui.link("https://rezi.dev/docs/getting-started", "Getting Started"),
ui.link("https://rezi.dev/docs/widgets", "Widget Reference"),
ui.link("https://rezi.dev/docs/examples", "Examples"),
ui.spacer({ size: 1 }),
ui.text("Community", { variant: "heading" }),
ui.link("https://github.com/rezi-ui/rezi/discussions", "Discussions"),
ui.link("https://discord.gg/rezi", "Discord Server"),
ui.link("https://twitter.com/reziframework", "Twitter"),
]),
]);
Reference List
import { ui } from "@rezi-ui/core";
const references = [
{ title: "API Documentation", url: "https://rezi.dev/api" },
{ title: "GitHub Repository", url: "https://github.com/rezi-ui/rezi" },
{ title: "npm Package", url: "https://npmjs.com/package/@rezi-ui/core" },
{ title: "Release Notes", url: "https://rezi.dev/releases" },
];
ui.column(
{ gap: 0 },
references.map((ref) =>
ui.row({ gap: 1, key: ref.url }, [
ui.text("→", { style: { dim: true } }),
ui.link(ref.url, ref.title),
])
)
);
import { ui } from "@rezi-ui/core";
ui.dropdown({
id: "help-menu",
anchorId: "help-button",
items: [
{
id: "docs",
label: "Documentation",
onPress: () => openLink("https://rezi.dev/docs"),
},
{
id: "issues",
label: "Report Issue",
onPress: () => openLink("https://github.com/rezi-ui/rezi/issues"),
},
{ id: "divider", label: "", divider: true },
{
id: "about",
label: "About Rezi",
onPress: () => app.update({ showAboutDialog: true }),
},
],
onClose: () => app.update({ helpMenuOpen: false }),
});
Accessibility
- Links are keyboard navigable with Tab
- Enter and Space keys activate links
- Use
accessibleLabel for descriptive announcements
- Disabled links are not focusable
- Focus indicators are shown when navigating with keyboard
- Button - For local actions without URLs
- Breadcrumb - For navigation path display
- Text - For non-interactive text content
Location in Source
- Types:
packages/core/src/widgets/types.ts:623-640
- Factory:
packages/core/src/widgets/ui.ts:681-699