Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6cdade4

Browse filesBrowse files
ascorbicsarah11918
andauthored
fix: updates types for live collection entries (#14548)
* Add "rendered" type * Remove maxAge * Apply suggestions from code review Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --------- Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com>
1 parent af801ca commit 6cdade4
Copy full SHA for 6cdade4

7 files changed

+104-37Lines changed: 104 additions & 37 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎.changeset/plain-women-double.md‎

Copy file name to clipboard
+29Lines changed: 29 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
#### :warning: Breaking change for live content collections only
6+
7+
Removes support for the `maxAge` property in `cacheHint` objects returned by live loaders. This did not make sense to set at the loader level, since the loader does not know how long each individual entry should be cached for.
8+
9+
If your live loader returns cache hints with `maxAge`, you need to remove this property:
10+
11+
```diff
12+
return {
13+
entries: [...],
14+
cacheHint: {
15+
tags: ['my-tag'],
16+
- maxAge: 60,
17+
lastModified: new Date(),
18+
},
19+
};
20+
```
21+
22+
The `cacheHint` object now only supports `tags` and `lastModified` properties. If you want to set the max age for a page, you can set the headers manually:
23+
24+
```astro
25+
---
26+
Astro.headers.set('cdn-cache-control', 'maxage=3600');
27+
---
28+
```
29+
Collapse file

‎.changeset/tasty-snails-smile.md‎

Copy file name to clipboard
+9Lines changed: 9 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Adds missing `rendered` property to experimental live collections entry type
6+
7+
Live collections support a `rendered` property that allows you to provide pre-rendered HTML for each entry. While this property was documented and implemented, it was missing from the TypeScript types. This could lead to type errors when trying to use it in a TypeScript project.
8+
9+
No changes to your project code are necessary. You can continue to use the `rendered` property as before, and it will no longer produce TypeScript errors.
Collapse file

‎packages/astro/src/content/runtime.ts‎

Copy file name to clipboardExpand all lines: packages/astro/src/content/runtime.ts
+1-14Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ export function createCollectionToGlobResultMap({
7171

7272
const cacheHintSchema = z.object({
7373
tags: z.array(z.string()).optional(),
74-
maxAge: z.number().optional(),
7574
lastModified: z.date().optional(),
7675
});
7776

@@ -529,19 +528,13 @@ export function createGetLiveCollection({
529528
// Aggregate cache hints from individual entries if any
530529
if (processedEntries.length > 0) {
531530
const entryTags = new Set<string>();
532-
let minMaxAge: number | undefined;
533531
let latestModified: Date | undefined;
534532

535533
for (const entry of processedEntries) {
536534
if (entry.cacheHint) {
537535
if (entry.cacheHint.tags) {
538536
entry.cacheHint.tags.forEach((tag) => entryTags.add(tag));
539537
}
540-
if (typeof entry.cacheHint.maxAge === 'number') {
541-
if (minMaxAge === undefined || entry.cacheHint.maxAge < minMaxAge) {
542-
minMaxAge = entry.cacheHint.maxAge;
543-
}
544-
}
545538
if (entry.cacheHint.lastModified instanceof Date) {
546539
if (latestModified === undefined || entry.cacheHint.lastModified > latestModified) {
547540
latestModified = entry.cacheHint.lastModified;
@@ -551,18 +544,12 @@ export function createGetLiveCollection({
551544
}
552545

553546
// Merge collection and entry cache hints
554-
if (entryTags.size > 0 || minMaxAge !== undefined || latestModified || cacheHint) {
547+
if (entryTags.size > 0 || latestModified || cacheHint) {
555548
const mergedCacheHint: CacheHint = {};
556549
if (cacheHint?.tags || entryTags.size > 0) {
557550
// Merge and dedupe tags
558551
mergedCacheHint.tags = [...new Set([...(cacheHint?.tags || []), ...entryTags])];
559552
}
560-
if (cacheHint?.maxAge !== undefined || minMaxAge !== undefined) {
561-
mergedCacheHint.maxAge =
562-
cacheHint?.maxAge !== undefined && minMaxAge !== undefined
563-
? Math.min(cacheHint.maxAge, minMaxAge)
564-
: (cacheHint?.maxAge ?? minMaxAge);
565-
}
566553
if (cacheHint?.lastModified && latestModified) {
567554
mergedCacheHint.lastModified =
568555
cacheHint.lastModified > latestModified ? cacheHint.lastModified : latestModified;
Collapse file

‎packages/astro/src/types/public/content.ts‎

Copy file name to clipboardExpand all lines: packages/astro/src/types/public/content.ts
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ export type GetDataEntryInfoReturnType = { data: Record<string, unknown>; rawDat
129129
export interface CacheHint {
130130
/** Cache tags */
131131
tags?: Array<string>;
132-
/** Maximum age of the response in seconds */
133-
maxAge?: number;
134132
/** Last modified time of the content */
135133
lastModified?: Date;
136134
}
@@ -140,6 +138,10 @@ export interface LiveDataEntry<TData extends Record<string, any> = Record<string
140138
id: string;
141139
/** The parsed entry data */
142140
data: TData;
141+
/** Optional rendered content */
142+
rendered?: {
143+
html: string;
144+
};
143145
/** A hint for how to cache this entry */
144146
cacheHint?: CacheHint;
145147
}
Collapse file

‎packages/astro/test/fixtures/live-loaders/src/live.config.ts‎

Copy file name to clipboardExpand all lines: packages/astro/test/fixtures/live-loaders/src/live.config.ts
+5-3Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ type EntryFilter = {
1717
};
1818

1919
const entries = {
20-
'123': { id: '123', data: { title: 'Page 123', age: 10 } },
20+
'123': {
21+
id: '123',
22+
data: { title: 'Page 123', age: 10 },
23+
rendered: { html: '<h1>Page 123</h1><p>This is rendered content.</p>' }
24+
},
2125
'456': { id: '456', data: { title: 'Page 456', age: 20 } },
2226
'789': { id: '789', data: { title: 'Page 789', age: 30 } },
2327
};
@@ -50,7 +54,6 @@ const loader: LiveLoader<Entry, EntryFilter, CollectionFilter, CustomError> = {
5054
},
5155
cacheHint: {
5256
tags: [`page:${filter.id}`],
53-
maxAge: 60,
5457
lastModified: new Date('2025-01-01T00:00:00.000Z'),
5558
},
5659
};
@@ -68,7 +71,6 @@ const loader: LiveLoader<Entry, EntryFilter, CollectionFilter, CustomError> = {
6871
: Object.values(entries),
6972
cacheHint: {
7073
tags: ['page'],
71-
maxAge: 60,
7274
lastModified: new Date('2025-01-02T00:00:00.000Z'),
7375
},
7476
};
Collapse file
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
import { getLiveEntry, render } from "astro:content";
3+
4+
const { entry } = await getLiveEntry("liveStuff", "123");
5+
6+
if (!entry) {
7+
return new Response(null, { status: 404 });
8+
}
9+
10+
const { Content } = await render(entry);
11+
12+
export const prerender = false;
13+
---
14+
15+
<html lang="en">
16+
<head>
17+
<meta charset="utf-8" />
18+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
19+
<meta name="viewport" content="width=device-width" />
20+
<meta name="generator" content={Astro.generator} />
21+
<title>Rendered Content Test</title>
22+
</head>
23+
<body>
24+
<div id="rendered-content">
25+
<Content />
26+
</div>
27+
</body>
28+
</html>
Collapse file

‎packages/astro/test/live-loaders.test.js‎

Copy file name to clipboardExpand all lines: packages/astro/test/live-loaders.test.js
+28-18Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,14 @@ describe('Live content collections', () => {
4545
entry: {
4646
id: '123',
4747
data: { title: 'Page 123', age: 10 },
48+
rendered: { html: '<h1>Page 123</h1><p>This is rendered content.</p>' },
4849
cacheHint: {
4950
tags: [`page:123`],
50-
maxAge: 60,
51-
lastModified: '2025-01-01T00:00:00.000Z',
51+
lastModified: '2025-01-01T00:00:00.000Z',
5252
},
5353
},
5454
cacheHint: {
5555
tags: [`page:123`],
56-
maxAge: 60,
5756
lastModified: '2025-01-01T00:00:00.000Z',
5857
},
5958
});
@@ -63,13 +62,11 @@ describe('Live content collections', () => {
6362
data: { title: 'Page 456', age: 20 },
6463
cacheHint: {
6564
tags: [`page:456`],
66-
maxAge: 60,
67-
lastModified: '2025-01-01T00:00:00.000Z',
65+
lastModified: '2025-01-01T00:00:00.000Z',
6866
},
6967
},
7068
cacheHint: {
7169
tags: [`page:456`],
72-
maxAge: 60,
7370
lastModified: '2025-01-01T00:00:00.000Z',
7471
},
7572
});
@@ -78,6 +75,7 @@ describe('Live content collections', () => {
7875
{
7976
id: '123',
8077
data: { title: 'Page 123', age: 10 },
78+
rendered: { html: '<h1>Page 123</h1><p>This is rendered content.</p>' },
8179
},
8280
{
8381
id: '456',
@@ -90,7 +88,6 @@ describe('Live content collections', () => {
9088
],
9189
cacheHint: {
9290
tags: ['page'],
93-
maxAge: 60,
9491
lastModified: '2025-01-02T00:00:00.000Z',
9592
},
9693
});
@@ -109,14 +106,12 @@ describe('Live content collections', () => {
109106
cacheHint: {
110107
lastModified: '2025-01-01T00:00:00.000Z',
111108
tags: [`page:456`],
112-
maxAge: 60,
113-
},
109+
},
114110
},
115111
cacheHint: {
116112
lastModified: '2025-01-01T00:00:00.000Z',
117113
tags: [`page:456`],
118-
maxAge: 60,
119-
},
114+
},
120115
},
121116
'passes dynamic filter to getEntry',
122117
);
@@ -126,6 +121,7 @@ describe('Live content collections', () => {
126121
{
127122
id: '123',
128123
data: { title: 'Page 123', age: 15 },
124+
rendered: { html: '<h1>Page 123</h1><p>This is rendered content.</p>' },
129125
},
130126
{
131127
id: '456',
@@ -154,6 +150,14 @@ describe('Live content collections', () => {
154150
const data = await response.json();
155151
assert.ok(data.error.includes('Use getLiveCollection() instead of getCollection()'));
156152
});
153+
154+
it('can render live entry with rendered content', async () => {
155+
const response = await fixture.fetch('/rendered');
156+
assert.equal(response.status, 200);
157+
const html = await response.text();
158+
assert.ok(html.includes('<h1>Page 123</h1>'));
159+
assert.ok(html.includes('<p>This is rendered content.</p>'));
160+
});
157161
});
158162

159163
describe('SSR', () => {
@@ -174,16 +178,15 @@ describe('Live content collections', () => {
174178
entry: {
175179
id: '123',
176180
data: { title: 'Page 123', age: 10 },
181+
rendered: { html: '<h1>Page 123</h1><p>This is rendered content.</p>' },
177182
cacheHint: {
178183
lastModified: '2025-01-01T00:00:00.000Z',
179184
tags: [`page:123`],
180-
maxAge: 60,
181-
},
185+
},
182186
},
183187
cacheHint: {
184188
lastModified: '2025-01-01T00:00:00.000Z',
185189
tags: [`page:123`],
186-
maxAge: 60,
187190
},
188191
});
189192
});
@@ -202,14 +205,12 @@ describe('Live content collections', () => {
202205
cacheHint: {
203206
lastModified: '2025-01-01T00:00:00.000Z',
204207
tags: [`page:456`],
205-
maxAge: 60,
206-
},
208+
},
207209
},
208210
cacheHint: {
209211
lastModified: '2025-01-01T00:00:00.000Z',
210212
tags: [`page:456`],
211-
maxAge: 60,
212-
},
213+
},
213214
},
214215
'passes dynamic filter to getEntry',
215216
);
@@ -222,5 +223,14 @@ describe('Live content collections', () => {
222223
const data = await response.json();
223224
assert.ok(data.error.includes('Use getLiveCollection() instead of getCollection()'));
224225
});
226+
227+
it('can render live entry with rendered content', async () => {
228+
const request = new Request('http://example.com/rendered');
229+
const response = await app.render(request);
230+
assert.equal(response.status, 200);
231+
const html = await response.text();
232+
assert.ok(html.includes('<h1>Page 123</h1>'));
233+
assert.ok(html.includes('<p>This is rendered content.</p>'));
234+
});
225235
});
226236
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.