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

pre-fetched-content.mddocs/

0

# Pre-fetched Content Processing

1

2

Parse pre-fetched HTML content to extract link preview metadata without making additional HTTP requests. Ideal for scenarios where content is already available from other sources or when implementing custom fetching logic.

3

4

## Capabilities

5

6

### getPreviewFromContent Function

7

8

Processes pre-fetched response objects to extract comprehensive link preview metadata using the same parsing logic as `getLinkPreview` but without making HTTP requests.

9

10

```typescript { .api }

11

/**

12

* Skip HTTP fetching and parse pre-fetched content for link preview metadata

13

* @param response - Pre-fetched response object with URL, headers, and HTML data

14

* @param options - Configuration options for parsing

15

* @returns Promise resolving to preview information object

16

* @throws Error if invalid response object or parsing fails

17

*/

18

function getPreviewFromContent(

19

response: IPreFetchedResource,

20

options?: ILinkPreviewOptions

21

): Promise<ILinkPreviewResponse>;

22

```

23

24

**Basic Usage:**

25

26

```typescript

27

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

28

29

// Pre-fetched response object

30

const prefetchedResponse = {

31

url: "https://www.example.com",

32

headers: {

33

"content-type": "text/html; charset=utf-8"

34

},

35

data: `<!DOCTYPE html>

36

<html>

37

<head>

38

<title>Example Site</title>

39

<meta property="og:title" content="Example Site">

40

<meta property="og:description" content="This is an example website">

41

<meta property="og:image" content="https://example.com/image.jpg">

42

</head>

43

<body>...</body>

44

</html>`

45

};

46

47

const preview = await getPreviewFromContent(prefetchedResponse);

48

console.log(preview.title); // "Example Site"

49

console.log(preview.description); // "This is an example website"

50

```

51

52

**Advanced Usage with Custom Fetching:**

53

54

```typescript

55

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

56

import axios from "axios";

57

58

// Custom fetch implementation

59

async function customPreviewExtraction(url: string) {

60

try {

61

const response = await axios.get(url, {

62

headers: {

63

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

64

"Accept": "text/html,application/xhtml+xml"

65

},

66

timeout: 10000

67

});

68

69

const prefetchedResource = {

70

url: response.config.url || url,

71

headers: response.headers,

72

data: response.data,

73

status: response.status

74

};

75

76

return await getPreviewFromContent(prefetchedResource, {

77

imagesPropertyType: "og"

78

});

79

} catch (error) {

80

throw new Error(`Custom fetch failed: ${error.message}`);

81

}

82

}

83

84

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

85

```

86

87

**Integration with Existing HTTP Clients:**

88

89

```typescript

90

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

91

import fetch from "node-fetch";

92

93

// Using node-fetch

94

async function fetchAndParse(url: string) {

95

const response = await fetch(url, {

96

headers: {

97

"User-Agent": "MyApp/1.0"

98

}

99

});

100

101

const headers: Record<string, string> = {};

102

response.headers.forEach((value, key) => {

103

headers[key] = value;

104

});

105

106

const prefetchedResource = {

107

url: response.url,

108

headers,

109

data: await response.text(),

110

status: response.status

111

};

112

113

return await getPreviewFromContent(prefetchedResource);

114

}

115

```

116

117

### Required Response Object Structure

118

119

The `IPreFetchedResource` interface defines the required structure for pre-fetched content:

120

121

```typescript { .api }

122

interface IPreFetchedResource {

123

/** HTTP response headers */

124

headers: Record<string, string>;

125

/** HTTP status code (optional) */

126

status?: number;

127

/** Property type for image meta tags (optional) */

128

imagesPropertyType?: string;

129

/** Proxy URL used (optional) */

130

proxyUrl?: string;

131

/** The URL that was fetched */

132

url: string;

133

/** The HTML content/response body */

134

data: string;

135

}

136

```

137

138

**Minimum Required Fields:**

139

140

```typescript

141

// Minimal valid response object

142

const minimalResponse = {

143

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

144

headers: {

145

"content-type": "text/html"

146

},

147

data: "<html><head><title>Example</title></head></html>"

148

};

149

```

150

151

**Complete Response Object:**

152

153

```typescript

154

// Complete response object with all optional fields

155

const completeResponse = {

156

url: "https://example.com/page",

157

headers: {

158

"content-type": "text/html; charset=utf-8",

159

"server": "nginx/1.18.0",

160

"last-modified": "Wed, 21 Oct 2015 07:28:00 GMT"

161

},

162

status: 200,

163

data: `<!DOCTYPE html>

164

<html>

165

<head>

166

<title>Complete Example</title>

167

<meta property="og:title" content="Complete Example Page">

168

<meta property="og:description" content="A complete example with all metadata">

169

<meta property="og:image" content="https://example.com/og-image.jpg">

170

<meta property="og:video" content="https://example.com/video.mp4">

171

<link rel="icon" href="/favicon.ico">

172

</head>

173

<body>

174

<h1>Page Content</h1>

175

<p>This is the main content of the page.</p>

176

</body>

177

</html>`

178

};

179

```

180

181

### Content Type Processing

182

183

The function processes different content types based on the `content-type` header:

184

185

**HTML Content (text/html):**

186

- Parses DOM using Cheerio

187

- Extracts OpenGraph meta tags

188

- Falls back to standard HTML meta tags

189

- Extracts images, videos, and favicons

190

- Supports custom response processing via `onResponse` callback

191

192

**Image Content (image/*):**

193

- Returns media type "image"

194

- Includes content type and default favicon

195

- No HTML parsing required

196

197

**Audio Content (audio/*):**

198

- Returns media type "audio"

199

- Includes content type and default favicon

200

201

**Video Content (video/*):**

202

- Returns media type "video"

203

- Includes content type and default favicon

204

205

**Application Content (application/*):**

206

- Returns media type "application"

207

- Includes content type and default favicon

208

209

**Unknown Content Types:**

210

- Attempts HTML parsing as fallback

211

- May extract partial metadata if HTML-like content

212

213

### Error Handling

214

215

The function validates input and throws descriptive errors:

216

217

```typescript

218

// Invalid response object

219

try {

220

await getPreviewFromContent(null);

221

} catch (error) {

222

// "link-preview-js did not receive a valid response object"

223

}

224

225

// Missing URL

226

try {

227

await getPreviewFromContent({

228

headers: {},

229

data: "<html></html>"

230

// Missing required 'url' field

231

});

232

} catch (error) {

233

// "link-preview-js did not receive a valid response object"

234

}

235

236

// Parsing errors

237

try {

238

await getPreviewFromContent({

239

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

240

headers: { "content-type": "text/html" },

241

data: "invalid html content"

242

});

243

} catch (error) {

244

// "link-preview-js could not fetch link information [parsing error details]"

245

}

246

```

247

248

### Use Cases

249

250

**Server-Side Rendering:**

251

```typescript

252

// Pre-fetch during server-side rendering

253

export async function getStaticProps({ params }) {

254

const response = await fetch(params.url);

255

const prefetchedData = {

256

url: response.url,

257

headers: Object.fromEntries(response.headers.entries()),

258

data: await response.text()

259

};

260

261

const preview = await getPreviewFromContent(prefetchedData);

262

263

return {

264

props: { preview },

265

revalidate: 3600 // Cache for 1 hour

266

};

267

}

268

```

269

270

**Batch Processing:**

271

```typescript

272

// Process multiple URLs efficiently

273

async function batchProcessUrls(urls: string[]) {

274

const responses = await Promise.all(

275

urls.map(url => fetch(url).then(r => ({

276

url: r.url,

277

headers: Object.fromEntries(r.headers.entries()),

278

data: r.text()

279

})))

280

);

281

282

return Promise.all(

283

responses.map(response => getPreviewFromContent(response))

284

);

285

}

286

```

287

288

**Custom Caching:**

289

```typescript

290

// Implement custom caching layer

291

class PreviewCache {

292

private cache = new Map();

293

294

async getPreview(url: string) {

295

if (this.cache.has(url)) {

296

const cached = this.cache.get(url);

297

return await getPreviewFromContent(cached);

298

}

299

300

const response = await fetch(url);

301

const prefetchedData = {

302

url: response.url,

303

headers: Object.fromEntries(response.headers.entries()),

304

data: await response.text()

305

};

306

307

this.cache.set(url, prefetchedData);

308

return await getPreviewFromContent(prefetchedData);

309

}

310

}

311

```