https://github.com/azizbecha/react-native-preview-url
Link Previews made easy 🚀
https://github.com/azizbecha/react-native-preview-url
react reactnative
Last synced: 2 months ago
JSON representation
Link Previews made easy 🚀
- Host: GitHub
- URL: https://github.com/azizbecha/react-native-preview-url
- Owner: azizbecha
- License: mit
- Created: 2025-08-10T14:07:40.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2026-04-25T20:23:42.000Z (2 months ago)
- Last Synced: 2026-04-25T20:31:09.492Z (2 months ago)
- Topics: react, reactnative
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/react-native-preview-url
- Size: 1.85 MB
- Stars: 6
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# React Native Preview Url
A React Native library that provides an easy way to fetch and display link previews using the `useUrlPreview` hook and a customizable `` component.
It uses our own open-source free open source API `azizbecha-link-preview-api` available on GitHub at [https://github.com/azizbecha/link-preview-api](https://github.com/azizbecha/link-preview-api).
You can use the API for free without an API key or host it yourself if you prefer.
## Features
- Fetches metadata (title, description, images, favicons, etc.) from URLs
- Customizable preview component with styles and fallback support
- Supports timeout and error handling
- Handles URL validation and loading states
## Installation
```bash
npm install react-native-preview-url
# or
yarn add react-native-preview-url
```
## Usage
### useUrlPreview Hook
```tsx
import { useUrlPreview } from 'react-native-preview-url';
const { loading, data, error } = useUrlPreview('https://github.com');
```
### `` Component
```tsx
import React from 'react';
import { LinkPreview } from 'react-native-preview-url';
export const Example = () => (
console.log(metadata)}
onError={(error) => console.error(error)}
onPress={() => console.log('Pressed preview')}
containerStyle={{ margin: 16, borderRadius: 8, backgroundColor: '#fff' }}
imageStyle={{ borderRadius: 8, height: 150 }}
titleStyle={{ fontSize: 18, fontWeight: 'bold' }}
descriptionStyle={{ fontSize: 14, color: '#555' }}
urlStyle={{ fontSize: 12, color: 'grey' }}
titleLines={2}
descriptionLines={3}
showUrl={true}
hideImage={false}
/>
);
```
## Caching
Responses are cached in memory and shared across every `` and `useUrlPreview` call, so rendering the same URL twice (or ten times, or on a later screen) fires only a single network request. Concurrent requests for the same URL are deduplicated automatically. Errors are cached too (under a separate, shorter TTL) to avoid hammering a failing endpoint.
Defaults: up to 50 entries, 5-minute success TTL, 30-second error TTL, enabled.
```tsx
import {
configureCache,
clearCache,
invalidateUrl,
} from 'react-native-preview-url';
// Tune at app startup
configureCache({
maxSize: 100,
ttl: 10 * 60 * 1000, // success TTL
errorTtl: 60 * 1000, // error TTL
});
// Drop everything (e.g. on pull-to-refresh)
clearCache();
// Drop a single URL (success or error)
invalidateUrl('https://github.com');
// Disable entirely
configureCache({ enabled: false });
```
Notes:
- Cache keys are scoped by base URL, so calling `setBaseUrl(...)` mid-session does not poison entries from a different environment.
- Timeout errors are not cached (they're treated as transient).
- `configureCache(...)` resets the cache when called.
## Props
| Prop | Type | Required | Default | Description |
| ------------------ | ------------------------------------- | -------- | ------------------- | ------------------------------------------------------------------ |
| `url` | `string` | Yes | - | The URL to fetch metadata for |
| `timeout` | `number` | No | `3000` | Fetch timeout in milliseconds |
| `onSuccess` | `(data: LinkPreviewResponse) => void` | No | - | Callback when data is successfully fetched |
| `onError` | `(error: string) => void` | No | - | Callback when fetching metadata fails |
| `onPress` | `(data: LinkPreviewResponse) => void` | No | - | Callback when pressed; if omitted, the URL is opened via `Linking` |
| `containerStyle` | `ViewStyle` | No | - | Style for the container view |
| `imageStyle` | `ImageStyle` | No | - | Style for the preview image |
| `titleStyle` | `TextStyle` | No | - | Style for the title text |
| `descriptionStyle` | `TextStyle` | No | - | Style for the description text |
| `urlStyle` | `TextStyle` | No | - | Style for the URL text |
| `titleLines` | `number` | No | 2 | Number of lines for title text truncation |
| `descriptionLines` | `number` | No | 4 | Number of lines for description text truncation |
| `showUrl` | `boolean` | No | `true` | Whether to show the URL domain below the description |
| `hideImage` | `boolean` | No | `false` | Whether to hide the preview image |
| `visible` | `boolean` | No | `true` | Whether to show or hide the preview component |
| `loaderComponent` | `ReactNode` | No | `ActivityIndicator` | Custom loading component |
| `fallbackImage` | `ImageSourcePropType` | No | `undefined` | Fallback image in case the website doesn't have one |
## Example Response Object
```json
{
"status": 200,
"title": "azizbecha - Overview",
"description": "I'm fixing bugs now, I'll write a bio later. azizbecha has 26 repositories available. Follow their code on GitHub.",
"url": "https://github.com/azizbecha",
"images": ["https://avatars.githubusercontent.com/u/63454940?v=4?s=400"],
"favicons": ["https://github.githubassets.com/favicons/favicon.svg"],
"mediaType": "profile",
"contentType": "text/html",
"siteName": "GitHub"
}
```
## License
MIT License