or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdlink-preview.mdpre-fetched-content.mdsecurity-configuration.md
tile.json

link-preview.mddocs/

0

# Link Preview Extraction

1

2

Comprehensive link preview generation from URLs or text containing URLs with automatic URL detection, HTTP fetching, and rich metadata extraction.

3

4

## Capabilities

5

6

### getLinkPreview Function

7

8

Parses text to find the first valid HTTP(S) URL, fetches the content, and extracts comprehensive link preview metadata including titles, descriptions, images, videos, and favicons.

9

10

```typescript { .api }

11

/**

12

* Parses text to find first HTTP(S) URL, fetches content, and extracts link preview metadata

13

* @param text - URL or text containing a URL to be parsed

14

* @param options - Configuration options for request and parsing

15

* @returns Promise resolving to preview information object

16

* @throws Error if no valid URL found, request timeout, or parsing fails

17

*/

18

function getLinkPreview(

19

text: string,

20

options?: ILinkPreviewOptions

21

): Promise<ILinkPreviewResponse>;

22

```

23

24

**Basic Usage:**

25

26

```typescript

27

import { getLinkPreview } from "link-preview-js";

28

29

// Direct URL

30

const preview = await getLinkPreview("https://www.example.com");

31

32

// Text containing URL

33

const textPreview = await getLinkPreview(

34

"Check out this site: https://www.example.com - it's amazing!"

35

);

36

37

// URL with newlines

38

const cleanPreview = await getLinkPreview(`

39

https://www.example.com

40

`);

41

```

42

43

**Advanced Usage with Options:**

44

45

```typescript

46

import { getLinkPreview } from "link-preview-js";

47

48

// Custom headers and timeout

49

const preview = await getLinkPreview("https://www.example.com", {

50

headers: {

51

"User-Agent": "MyBot/1.0",

52

"Accept-Language": "en-US"

53

},

54

timeout: 5000,

55

imagesPropertyType: "og"

56

});

57

58

// Using proxy

59

const proxyPreview = await getLinkPreview("https://www.example.com", {

60

proxyUrl: "https://cors-proxy.example.com/",

61

headers: {

62

"Origin": "https://myapp.com"

63

}

64

});

65

66

// With custom response processing

67

const customPreview = await getLinkPreview("https://www.example.com", {

68

onResponse: (response, doc, url) => {

69

// Add custom logic for specific sites

70

if (url?.hostname === "example.com") {

71

response.siteName = "Custom Example Site";

72

}

73

74

// Fallback description from first paragraph

75

if (!response.description) {

76

response.description = doc('p').first().text();

77

}

78

79

return response;

80

}

81

});

82

```

83

84

### URL Detection and Validation

85

86

The function automatically detects and validates URLs using sophisticated regex patterns that:

87

88

- Match HTTP and HTTPS protocols only

89

- Exclude private network IP ranges (10.x.x.x, 192.168.x.x, 172.16-31.x.x, 127.x.x.x)

90

- Validate domain names and TLD requirements

91

- Support international domain names

92

- Allow port numbers and URL paths

93

94

**Supported URL Formats:**

95

96

```typescript

97

// These URLs will be detected and processed:

98

"https://www.example.com"

99

"http://subdomain.example.org:8080/path?query=value"

100

"https://例え.テスト" // International domains

101

"Text before https://example.com text after" // URLs in text

102

103

// These will be rejected:

104

"https://192.168.1.1" // Private IP

105

"https://127.0.0.1" // Loopback

106

"ftp://example.com" // Unsupported protocol

107

"example.com" // Missing protocol

108

```

109

110

### Content Type Handling

111

112

The function handles different content types automatically:

113

114

**HTML/Text Content:**

115

- Extracts OpenGraph tags (`og:title`, `og:description`, `og:image`, etc.)

116

- Falls back to standard HTML meta tags

117

- Parses Twitter Card metadata

118

- Extracts favicon links and provides default fallback

119

120

**Media Files:**

121

- **Images**: Returns media type "image" with content type and default favicon

122

- **Audio**: Returns media type "audio" with content type and default favicon

123

- **Video**: Returns media type "video" with content type and default favicon

124

- **Applications**: Returns media type "application" with content type and default favicon

125

126

### Error Handling

127

128

The function throws descriptive errors for various failure scenarios:

129

130

```typescript

131

// Error examples

132

try {

133

await getLinkPreview("no url here");

134

} catch (error) {

135

// "link-preview-js did not receive a valid a url or text"

136

}

137

138

try {

139

await getLinkPreview("https://slow-site.com", { timeout: 1000 });

140

} catch (error) {

141

// "Request timeout"

142

}

143

144

try {

145

await getLinkPreview("https://redirect-site.com", {

146

followRedirects: "manual"

147

// Missing handleRedirects function

148

});

149

} catch (error) {

150

// "link-preview-js followRedirects is set to manual, but no handleRedirects function was provided"

151

}

152

```

153

154

## Response Structure

155

156

```typescript { .api }

157

interface ILinkPreviewResponse {

158

/** The resolved URL that was processed */

159

url: string;

160

/** Page title from meta tags or HTML title element */

161

title: string;

162

/** Site name from og:site_name meta tag */

163

siteName: string | undefined;

164

/** Description from meta tags */

165

description: string | undefined;

166

/** Type of content (website, image, video, audio, application) */

167

mediaType: string;

168

/** HTTP Content-Type header value */

169

contentType: string | undefined;

170

/** Array of image URLs found in meta tags or img elements */

171

images: string[];

172

/** Array of video objects from og:video meta tags */

173

videos: IVideoType[];

174

/** Array of favicon URLs */

175

favicons: string[];

176

/** Character encoding parsed from Content-Type header (optional) */

177

charset?: string;

178

}

179

```

180

181

**Example Responses:**

182

183

HTML Page:

184

```json

185

{

186

"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",

187

"title": "Rick Astley - Never Gonna Give You Up",

188

"siteName": "YouTube",

189

"description": "The official video for Rick Astley's 1987 hit...",

190

"mediaType": "video.other",

191

"contentType": "text/html",

192

"images": ["https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg"],

193

"videos": [],

194

"favicons": ["https://www.youtube.com/favicon.ico"],

195

"charset": "utf-8"

196

}

197

```

198

199

Image File:

200

```json

201

{

202

"url": "https://example.com/image.jpg",

203

"mediaType": "image",

204

"contentType": "image/jpeg",

205

"favicons": ["https://example.com/favicon.ico"]

206

}

207

```