Introduction
Components
- Accordion
- Action Sheet
- Alert
- Audio Player
- Audio Recorder
- Audio Waveform
- Avatar
- Badge
- BottomSheet
- Button
- Camera
- Camera Preview
- Card
- Carousel
- Checkbox
- Collapsible
- Color Picker
- Combobox
- Date Picker
- File Picker
- Gallery
- Hello Wave
- Icon
- Image
- Input
- Input OTP
- Link
- MediaPicker
- Mode Toggle
- Onboarding
- ParallaxScrollView
- Picker
- Popover
- Progress
- Radio
- ScrollView
- SearchBar
- Separator
- Share
- Sheet
- Skeleton
- Spinner
- Switch
- Table
- Tabs
- Text
- Toast
- Toggle
- Video
- View
Charts
import { Link } from '@/components/ui/link';
import { View } from '@/components/ui/view';
import React from 'react';
export function LinkDemo() {
return (
<View style={{ gap: 12 }}>
<Link href='/'>Go to Profile</Link>
<Link href='/'>Settings</Link>
<Link href={{ pathname: '/', params: { id: '123' } }}>User Details</Link>
</View>
);
}
Installation
pnpm dlx bna-ui add link
Usage
import { Link } from '@/components/ui/link';
<Link href='/profile'>Go to Profile</Link>
<Link href='https://example.com' browser='external'>
Open in Browser
</Link>
Examples
Default Internal Navigation
import { Link } from '@/components/ui/link';
import { View } from '@/components/ui/view';
import React from 'react';
export function LinkDemo() {
return (
<View style={{ gap: 12 }}>
<Link href='/'>Go to Profile</Link>
<Link href='/'>Settings</Link>
<Link href={{ pathname: '/', params: { id: '123' } }}>User Details</Link>
</View>
);
}
External Links
import { Link } from '@/components/ui/link';
import { View } from '@/components/ui/view';
import React from 'react';
export function LinkExternal() {
return (
<View style={{ gap: 12 }}>
<Link href='https://github.com'>Visit GitHub</Link>
<Link href='https://expo.dev'>Expo Documentation</Link>
<Link href='https://reactnative.dev'>React Native Docs</Link>
</View>
);
}
Browser Options
import { Link } from '@/components/ui/link';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import React from 'react';
export function LinkBrowser() {
return (
<View style={{ gap: 16 }}>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>
In-App Browser (Default)
</Text>
<View style={{ gap: 6 }}>
<Link href='https://github.com' browser='in-app'>
Open GitHub in-app
</Link>
<Link href='https://expo.dev'>Open Expo docs in-app</Link>
</View>
</View>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>
External Browser
</Text>
<View style={{ gap: 6 }}>
<Link href='https://github.com' browser='external'>
Open GitHub externally
</Link>
<Link href='https://expo.dev' browser='external'>
Open Expo docs externally
</Link>
</View>
</View>
</View>
);
}
With Custom Children
import { Button } from '@/components/ui/button';
import { Link } from '@/components/ui/link';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { ExternalLink, HomeIcon, Mail } from 'lucide-react-native';
import React from 'react';
export function LinkCustom() {
return (
<View style={{ gap: 16 }}>
<Link href='/' asChild>
<Button icon={HomeIcon}>Welcome</Button>
</Link>
<Link href='https://github.com'>
<View
style={{
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
padding: 12,
backgroundColor: 'red',
borderRadius: 8,
}}
>
<ExternalLink size={16} color='#fff' />
<Text style={{ color: '#fff', textAlign: 'center' }}>
External Link
</Text>
</View>
</Link>
<Link href='mailto:contact@example.com' asChild>
<Button variant='success' icon={Mail}>
Send Email
</Button>
</Link>
</View>
);
}
Different Link Types
import { Link } from '@/components/ui/link';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import React from 'react';
export function LinkTypes() {
return (
<View style={{ gap: 16 }}>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>
Internal Navigation
</Text>
<View style={{ gap: 6 }}>
<Link href='/'>Home Page</Link>
<Link href='/'>About Us</Link>
<Link href={{ pathname: '/', params: { id: '123' } }}>
Product Details
</Link>
</View>
</View>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>External URLs</Text>
<View style={{ gap: 6 }}>
<Link href='https://google.com'>Google</Link>
<Link href='http://example.com'>Example Site</Link>
</View>
</View>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>
Communication Links
</Text>
<View style={{ gap: 6 }}>
<Link href='mailto:hello@example.com'>Send Email</Link>
<Link href='tel:+1234567890'>Call Phone</Link>
<Link href='mailto:support@company.com?subject=Help Request'>
Email with Subject
</Link>
<Link href='sms:+1234567890'>Send SMS</Link>
</View>
</View>
</View>
);
}
Styled Links
import { Link } from '@/components/ui/link';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import React from 'react';
export function LinkStyled() {
return (
<View style={{ gap: 16 }}>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>Default Styled</Text>
<View style={{ gap: 6 }}>
<Link href='/'>Default Link Style</Link>
<Link href='https://example.com'>External Link</Link>
</View>
</View>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>
Custom Text Styling
</Text>
<View style={{ gap: 6 }}>
<Link href='/'>
<Text
style={{
color: '#dc2626',
fontWeight: '600',
textDecorationLine: 'underline',
}}
>
Red Bold Link
</Text>
</Link>
<Link href='/'>
<Text
style={{
color: '#059669',
fontSize: 18,
fontStyle: 'italic',
}}
>
Green Italic Link
</Text>
</Link>
<Link href='https://github.com'>
<Text
style={{
color: '#7c3aed',
fontWeight: '700',
textTransform: 'uppercase',
letterSpacing: 1,
}}
>
Purple Uppercase
</Text>
</Link>
</View>
</View>
<View style={{ gap: 8 }}>
<Text style={{ fontWeight: '600', fontSize: 16 }}>Inline Links</Text>
<Text>
This is a paragraph with an <Link href='/'>inline link</Link> that
flows naturally with the text. You can also have{' '}
<Link href='https://example.com'>external inline links</Link> in your
content.
</Text>
</View>
</View>
);
}
Button-Style Links
import { Button } from '@/components/ui/button';
import { Link } from '@/components/ui/link';
import { View } from '@/components/ui/view';
import { ExternalLink, Settings, User } from 'lucide-react-native';
import React from 'react';
export function LinkButtons() {
return (
<View style={{ gap: 16 }}>
<View style={{ gap: 12 }}>
<Link href='/' asChild>
<Button variant='default' icon={User}>
View Profile
</Button>
</Link>
<Link href='/' asChild>
<Button variant='outline' icon={Settings}>
Open Settings
</Button>
</Link>
<Link href='https://github.com' browser='external' asChild>
<Button variant='secondary' icon={ExternalLink}>
Visit GitHub
</Button>
</Link>
</View>
<View style={{ flexDirection: 'row', gap: 12, flexWrap: 'wrap' }}>
<Link href='/' asChild>
<Button variant='default' size='sm'>
Dashboard
</Button>
</Link>
<Link href='/' asChild>
<Button variant='ghost' size='sm'>
Help
</Button>
</Link>
</View>
<View style={{ gap: 8 }}>
<Link href='/' asChild>
<Button variant='destructive' size='lg'>
Danger Zone
</Button>
</Link>
<Link href='/' asChild>
<Button variant='success' size='lg'>
Success Action
</Button>
</Link>
</View>
<Link href='mailto:support@example.com' asChild>
<Button variant='link' size='sm'>
Contact
</Button>
</Link>
</View>
);
}
API Reference
Link
The main link component that handles navigation and external URL opening.
Prop | Type | Default | Description |
---|---|---|---|
href | Href | - | The destination URL or route. Can be string or route object. |
browser | 'in-app' | 'external' | 'in-app' | How external links should open (in-app browser vs system browser). |
children | ReactNode | - | The content of the link. Can be text or custom components. |
All other props from expo-router
's Link
component are also supported.
Href Types
The href
prop accepts the following formats:
- Internal routes:
"/profile"
,"/settings"
,{ pathname: "/user", params: { id: "123" } }
- External URLs:
"https://example.com"
,"http://example.com"
- Email links:
"mailto:user@example.com"
- Phone links:
"tel:+1234567890"
Browser Behavior
In-App Browser (Default)
When browser="in-app"
(default), external links open in an in-app browser:
- Mobile: Uses
expo-web-browser
for a seamless in-app experience - Web: Opens in a new tab
External Browser
When browser="external"
, external links open in the system browser:
- Mobile: Uses the device's default browser app
- Web: Opens in a new tab
Accessibility
The Link component maintains accessibility features:
- Proper semantic link structure for screen readers
- Keyboard navigation support
- Focus management
- ARIA attributes when using custom children
- Text decoration for visual link indication
Platform Considerations
React Native
- Internal navigation uses Expo Router's navigation system
- External links use either
expo-web-browser
orLinking
API - Haptic feedback can be added through custom styling
Web
- Internal navigation uses client-side routing
- External links open in new tabs
- Standard web link behavior and styling apply
Best Practices
- Use descriptive link text that clearly indicates the destination
- Choose appropriate browser behavior based on user context
- Test on both platforms to ensure consistent behavior
- Consider loading states for external links that might take time to open
- Use custom children sparingly - text links are more accessible
On This Page
InstallationUsageExamplesDefault Internal NavigationExternal LinksBrowser OptionsWith Custom ChildrenDifferent Link TypesStyled LinksButton-Style LinksAPI ReferenceLinkHref TypesBrowser BehaviorIn-App Browser (Default)External BrowserAccessibilityPlatform ConsiderationsReact NativeWebBest Practices