mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
feat(next): ctx.isPrerendered (#11875)
This commit is contained in:
parent
70865b3cdc
commit
a8a3d2cde8
12 changed files with 97 additions and 16 deletions
22
.changeset/long-lions-do.md
Normal file
22
.changeset/long-lions-do.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Adds a new property `isPrerendered` to the globals `Astro` and `APIContext` . This boolean value represents whether or not the current page is prerendered:
|
||||
|
||||
```astro
|
||||
---
|
||||
// src/pages/index.astro
|
||||
|
||||
export const prerender = true
|
||||
---
|
||||
```
|
||||
|
||||
```js
|
||||
// src/middleware.js
|
||||
|
||||
export const onRequest = (ctx, next) => {
|
||||
console.log(ctx.prerender) // it will log true
|
||||
return next()
|
||||
}
|
||||
```
|
|
@ -5,7 +5,7 @@
|
|||
Adds a new property to the globals `Astro` and `APIContext` called `routePattern`. The `routePattern` represents the current route (component)
|
||||
that is being rendered by Astro. It's usually a path pattern will look like this: `blog/[slug]`:
|
||||
|
||||
```asto
|
||||
```astro
|
||||
---
|
||||
// src/pages/blog/[slug].astro
|
||||
const route = Astro.routePattern;
|
||||
|
|
|
@ -21,7 +21,7 @@ export type Locals = {
|
|||
};
|
||||
|
||||
export const onRequest = defineMiddleware(async (context, next) => {
|
||||
if ((context as any)._isPrerendered) {
|
||||
if (context.isPrerendered) {
|
||||
if (context.request.method === 'POST') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
|
|
|
@ -70,6 +70,7 @@ function createContext({
|
|||
},
|
||||
});
|
||||
},
|
||||
isPrerendered: false,
|
||||
get preferredLocale(): string | undefined {
|
||||
return (preferredLocale ??= computePreferredLocale(request, userDefinedLocales));
|
||||
},
|
||||
|
|
|
@ -107,8 +107,6 @@ export class RenderContext {
|
|||
const { cookies, middleware, pipeline } = this;
|
||||
const { logger, serverLike, streaming, manifest } = pipeline;
|
||||
|
||||
const isPrerendered = !serverLike || this.routeData.prerender;
|
||||
|
||||
const props =
|
||||
Object.keys(this.props).length > 0
|
||||
? this.props
|
||||
|
@ -121,7 +119,7 @@ export class RenderContext {
|
|||
serverLike,
|
||||
base: manifest.base,
|
||||
});
|
||||
const apiContext = this.createAPIContext(props, isPrerendered);
|
||||
const apiContext = this.createAPIContext(props);
|
||||
|
||||
this.counter++;
|
||||
if (this.counter === 4) {
|
||||
|
@ -208,7 +206,7 @@ export class RenderContext {
|
|||
return response;
|
||||
}
|
||||
|
||||
createAPIContext(props: APIContext['props'], isPrerendered: boolean): APIContext {
|
||||
createAPIContext(props: APIContext['props']): APIContext {
|
||||
const context = this.createActionAPIContext();
|
||||
const redirect = (path: string, status = 302) =>
|
||||
new Response(null, { status, headers: { Location: path } });
|
||||
|
@ -218,11 +216,6 @@ export class RenderContext {
|
|||
redirect,
|
||||
getActionResult: createGetActionResult(context.locals),
|
||||
callAction: createCallAction(context),
|
||||
// Used internally by Actions middleware.
|
||||
// TODO: discuss exposing this information from APIContext.
|
||||
// middleware runs on prerendered routes in the dev server,
|
||||
// so this is useful information to have.
|
||||
_isPrerendered: isPrerendered,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -261,6 +254,7 @@ export class RenderContext {
|
|||
return {
|
||||
cookies,
|
||||
routePattern: this.routeData.route,
|
||||
isPrerendered: this.routeData.prerender,
|
||||
get clientAddress() {
|
||||
return renderContext.clientAddress();
|
||||
},
|
||||
|
@ -446,6 +440,7 @@ export class RenderContext {
|
|||
generator: astroStaticPartial.generator,
|
||||
glob: astroStaticPartial.glob,
|
||||
routePattern: this.routeData.route,
|
||||
isPrerendered: this.routeData.prerender,
|
||||
cookies,
|
||||
get clientAddress() {
|
||||
return renderContext.clientAddress();
|
||||
|
|
|
@ -339,6 +339,11 @@ interface AstroSharedContext<
|
|||
* The current locale computed from the URL of the request. It matches the locales in `i18n.locales`, and returns `undefined` otherwise.
|
||||
*/
|
||||
currentLocale: string | undefined;
|
||||
|
||||
/**
|
||||
* Whether the current route is prerendered or not.
|
||||
*/
|
||||
isPrerendered: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('Astro Global', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('Astro.route.pattern has the right value in pages and components', async () => {
|
||||
it('Astro.routePattern has the right value in pages and components', async () => {
|
||||
let html = await fixture.fetch('/blog').then((res) => res.text());
|
||||
let $ = cheerio.load(html);
|
||||
assert.match($('#pattern').text(), /Astro route pattern: \//);
|
||||
|
@ -60,6 +60,18 @@ describe('Astro Global', () => {
|
|||
/Astro route pattern middleware: \/omit-markdown-extensions/,
|
||||
);
|
||||
});
|
||||
|
||||
it('Astro.isPrerendered has the right value in pages and components', async () => {
|
||||
let html = await fixture.fetch('/blog', {}).then((res) => res.text());
|
||||
let $ = cheerio.load(html);
|
||||
assert.match($('#prerender').text(), /Astro route prerender: true/);
|
||||
assert.match($('#prerender-middleware').text(), /Astro route prerender middleware: true/);
|
||||
|
||||
html = await fixture.fetch('/blog/about', {}).then((res) => res.text());
|
||||
$ = cheerio.load(html);
|
||||
assert.match($('#prerender').text(), /Astro route prerender: false/);
|
||||
assert.match($('#prerender-middleware').text(), /Astro route prerender middleware: false/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
|
@ -96,7 +108,7 @@ describe('Astro Global', () => {
|
|||
assert.equal($('.post-url[href]').length, 8);
|
||||
});
|
||||
|
||||
it('Astro.route.pattern has the right value in pages and components', async () => {
|
||||
it('Astro.routePattern has the right value in pages and components', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
assert.match($('#pattern').text(), /Astro route pattern: \//);
|
||||
|
@ -118,6 +130,19 @@ describe('Astro Global', () => {
|
|||
'Astro route pattern middleware: /posts/[page]',
|
||||
);
|
||||
});
|
||||
|
||||
it('Astro.isPrerendered has the right value in pages and components', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
assert.match($('#prerender').text(), /Astro route prerender: true/);
|
||||
assert.match($('#prerender-middleware').text(), /Astro route prerender middleware: true/);
|
||||
|
||||
html = await fixture.readFile('/about/index.html');
|
||||
$ = cheerio.load(html);
|
||||
// It's prerendered since there's no adapter
|
||||
assert.match($('#prerender').text(), /Astro route prerender: true/);
|
||||
assert.match($('#prerender-middleware').text(), /Astro route prerender middleware: true/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('app', () => {
|
||||
|
@ -143,7 +168,7 @@ describe('Astro Global', () => {
|
|||
assert.equal($('#site').attr('href'), 'https://mysite.dev/subsite/');
|
||||
});
|
||||
|
||||
it('Astro.route.pattern has the right value in pages and components', async () => {
|
||||
it('Astro.routePattern has the right value in pages and components', async () => {
|
||||
let response = await app.render(new Request('https://example.com/'));
|
||||
let html = await response.text();
|
||||
let $ = cheerio.load(html);
|
||||
|
@ -158,6 +183,19 @@ describe('Astro Global', () => {
|
|||
/Astro route pattern middleware: \/omit-markdown-extensions/,
|
||||
);
|
||||
});
|
||||
|
||||
it('Astro.isPrerendered has the right value in pages and components', async () => {
|
||||
let html = await app.render(new Request('https://example.com/')).then((res) => res.text());
|
||||
let $ = cheerio.load(html);
|
||||
// It's NOT prerendered since there's an adapter + output server
|
||||
assert.match($('#prerender').text(), /Astro route prerender: false/);
|
||||
assert.match($('#prerender-middleware').text(), /Astro route prerender middleware: false/);
|
||||
|
||||
html = await app.render(new Request('https://example.com/about')).then((res) => res.text());
|
||||
$ = cheerio.load(html);
|
||||
assert.match($('#prerender').text(), /Astro route prerender: false/);
|
||||
assert.match($('#prerender-middleware').text(), /Astro route prerender middleware: false/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
---
|
||||
const pattern = Astro.routePattern;
|
||||
const localsPattern = Astro.locals.localsPattern;
|
||||
const isPrerendered = JSON.stringify(Astro.isPrerendered);
|
||||
const localsPrerendered = JSON.stringify(Astro.locals.localsPrerendered);
|
||||
---
|
||||
<p id="pattern">Astro route pattern: {pattern}</p>
|
||||
<p id="pattern-middleware">Astro route pattern middleware: {localsPattern}</p>
|
||||
<p id="prerender">Astro route prerender: {isPrerendered}</p>
|
||||
<p id="prerender-middleware">Astro route prerender middleware: {localsPrerendered}</p>
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
export function onRequest(ctx, next) {
|
||||
ctx.locals = {
|
||||
localsPattern: ctx.routePattern
|
||||
localsPattern: ctx.routePattern,
|
||||
localsPrerendered: ctx.isPrerendered
|
||||
};
|
||||
return next()
|
||||
}
|
||||
|
|
13
packages/astro/test/fixtures/astro-global/src/pages/about.astro
vendored
Normal file
13
packages/astro/test/fixtures/astro-global/src/pages/about.astro
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
import Route from '../components/Route.astro'
|
||||
|
||||
export const prerender = false
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
<title>Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<Route />
|
||||
</body>
|
||||
</html>
|
|
@ -9,7 +9,7 @@ const data = await Astro.glob('./post/**/*');
|
|||
<body>
|
||||
{data.map((page: any) => (
|
||||
<div>
|
||||
<h1 data-file={page.file} />Title</h1>
|
||||
<h1 data-file={page.file}>Title</h1>
|
||||
<a class="post-url" href={page.url}>Read</a>
|
||||
</div>
|
||||
))}
|
||||
|
|
|
@ -8752,10 +8752,12 @@ packages:
|
|||
|
||||
libsql@0.3.19:
|
||||
resolution: {integrity: sha512-Aj5cQ5uk/6fHdmeW0TiXK42FqUlwx7ytmMLPSaUQPin5HKKKuUPD62MAbN4OEweGBBI7q1BekoEN4gPUEL6MZA==}
|
||||
cpu: [x64, arm64, wasm32]
|
||||
os: [darwin, linux, win32]
|
||||
|
||||
libsql@0.4.1:
|
||||
resolution: {integrity: sha512-qZlR9Yu1zMBeLChzkE/cKfoKV3Esp9cn9Vx5Zirn4AVhDWPcjYhKwbtJcMuHehgk3mH+fJr9qW+3vesBWbQpBg==}
|
||||
cpu: [x64, arm64, wasm32]
|
||||
os: [darwin, linux, win32]
|
||||
|
||||
lilconfig@2.1.0:
|
||||
|
|
Loading…
Reference in a new issue