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
```