mirror of
https://github.com/withastro/astro.git
synced 2025-04-07 23:41:43 -05:00
Partials (#8755)
* Fragment support * Add a changeset * Linting * debuggin * Rename to partial * Update the chagneset * Make work with mdx * Update .changeset/brave-pots-drop.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update .changeset/brave-pots-drop.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update .changeset/brave-pots-drop.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --------- Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
ec7f531682
commit
fe4079f05b
13 changed files with 117 additions and 5 deletions
24
.changeset/brave-pots-drop.md
Normal file
24
.changeset/brave-pots-drop.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Page Partials
|
||||
|
||||
A page component can now be identified as a **partial** page, which will render its HTML content without including a `<! DOCTYPE html>` declaration nor any `<head>` content.
|
||||
|
||||
A rendering library, like htmx or Stimulus or even just jQuery can access partial content on the client to dynamically update only parts of a page.
|
||||
|
||||
Pages marked as partials do not have a `doctype` or any head content included in the rendered result. You can mark any page as a partial by setting this option:
|
||||
|
||||
|
||||
```astro
|
||||
---
|
||||
export const partial = true;
|
||||
---
|
||||
|
||||
<li>This is a single list item.</li>
|
||||
```
|
||||
|
||||
Other valid page files that can export a value (e.g. `.mdx`) can also be marked as partials.
|
||||
|
||||
Read more about [Astro page partials](/en/core-concepts/astro-pages/#partials) in our documentation.
|
|
@ -1562,6 +1562,7 @@ export type AsyncRendererComponentFn<U> = (
|
|||
export interface ComponentInstance {
|
||||
default: AstroComponentFactory;
|
||||
css?: string[];
|
||||
partial?: boolean;
|
||||
prerender?: boolean;
|
||||
/**
|
||||
* Only used for logging if deprecated drafts feature is used
|
||||
|
@ -2234,6 +2235,7 @@ export interface SSRResult {
|
|||
*/
|
||||
clientDirectives: Map<string, string>;
|
||||
compressHTML: boolean;
|
||||
partial: boolean;
|
||||
/**
|
||||
* Only used for logging
|
||||
*/
|
||||
|
|
|
@ -49,6 +49,7 @@ export async function renderPage({ mod, renderContext, env, cookies }: RenderPag
|
|||
clientDirectives: env.clientDirectives,
|
||||
compressHTML: env.compressHTML,
|
||||
request: renderContext.request,
|
||||
partial: !!mod.partial,
|
||||
site: env.site,
|
||||
scripts: renderContext.scripts,
|
||||
ssr: env.ssr,
|
||||
|
|
|
@ -31,6 +31,7 @@ export interface CreateResultArgs {
|
|||
renderers: SSRLoadedRenderer[];
|
||||
clientDirectives: Map<string, string>;
|
||||
compressHTML: boolean;
|
||||
partial: boolean;
|
||||
resolve: (s: string) => Promise<string>;
|
||||
/**
|
||||
* Used for `Astro.site`
|
||||
|
@ -155,6 +156,7 @@ export function createResult(args: CreateResultArgs): SSRResult {
|
|||
renderers: args.renderers,
|
||||
clientDirectives: args.clientDirectives,
|
||||
compressHTML: args.compressHTML,
|
||||
partial: args.partial,
|
||||
pathname: args.pathname,
|
||||
cookies,
|
||||
/** This function returns the `Astro` faux-global */
|
||||
|
|
|
@ -33,7 +33,7 @@ export async function renderToString(
|
|||
// Automatic doctype insertion for pages
|
||||
if (isPage && !renderedFirstPageChunk) {
|
||||
renderedFirstPageChunk = true;
|
||||
if (!/<!doctype html/i.test(String(chunk))) {
|
||||
if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
|
||||
const doctype = result.compressHTML ? '<!DOCTYPE html>' : '<!DOCTYPE html>\n';
|
||||
str += doctype;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ export async function renderToReadableStream(
|
|||
// Automatic doctype insertion for pages
|
||||
if (isPage && !renderedFirstPageChunk) {
|
||||
renderedFirstPageChunk = true;
|
||||
if (!/<!doctype html/i.test(String(chunk))) {
|
||||
if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
|
||||
const doctype = result.compressHTML ? '<!DOCTYPE html>' : '<!DOCTYPE html>\n';
|
||||
controller.enqueue(encoder.encode(doctype));
|
||||
}
|
||||
|
|
|
@ -77,13 +77,13 @@ function stringifyChunk(
|
|||
}
|
||||
}
|
||||
case 'head': {
|
||||
if (result._metadata.hasRenderedHead) {
|
||||
if (result._metadata.hasRenderedHead || result.partial) {
|
||||
return '';
|
||||
}
|
||||
return renderAllHeadContent(result);
|
||||
}
|
||||
case 'maybe-head': {
|
||||
if (result._metadata.hasRenderedHead || result._metadata.headInTree) {
|
||||
if (result._metadata.hasRenderedHead || result._metadata.headInTree || result.partial) {
|
||||
return '';
|
||||
}
|
||||
return renderAllHeadContent(result);
|
||||
|
|
|
@ -505,7 +505,7 @@ export async function renderComponentToString(
|
|||
// Automatic doctype and head insertion for pages
|
||||
if (isPage && !renderedFirstPageChunk) {
|
||||
renderedFirstPageChunk = true;
|
||||
if (!/<!doctype html/i.test(String(chunk))) {
|
||||
if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
|
||||
const doctype = result.compressHTML ? '<!DOCTYPE html>' : '<!DOCTYPE html>\n';
|
||||
str += doctype + head;
|
||||
}
|
||||
|
|
9
packages/astro/test/fixtures/partials/astro.config.mjs
vendored
Normal file
9
packages/astro/test/fixtures/partials/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
mdx()
|
||||
]
|
||||
});
|
9
packages/astro/test/fixtures/partials/package.json
vendored
Normal file
9
packages/astro/test/fixtures/partials/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/partials",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/mdx": "workspace:*"
|
||||
}
|
||||
}
|
5
packages/astro/test/fixtures/partials/src/pages/partials/docs.mdx
vendored
Normal file
5
packages/astro/test/fixtures/partials/src/pages/partials/docs.mdx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
export const partial = true;
|
||||
|
||||
# This is heading
|
||||
|
||||
and this is some text
|
4
packages/astro/test/fixtures/partials/src/pages/partials/item.astro
vendored
Normal file
4
packages/astro/test/fixtures/partials/src/pages/partials/item.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
export const partial = true;
|
||||
---
|
||||
<li>This is a single line item</li>
|
47
packages/astro/test/partials.test.js
Normal file
47
packages/astro/test/partials.test.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { expect } from 'chai';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
describe('Partials', () => {
|
||||
/** @type {import('./test-utils.js').Fixture} */
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/partials/',
|
||||
});
|
||||
});
|
||||
|
||||
describe('dev', () => {
|
||||
/** @type {import('./test-utils.js').DevServer} */
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
it('is only the written HTML', async () => {
|
||||
const html = await fixture.fetch('/partials/item/').then((res) => res.text());
|
||||
expect(html.startsWith('<li>')).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('is only the written HTML', async () => {
|
||||
const html = await fixture.readFile('/partials/item/index.html');
|
||||
expect(html.startsWith('<li>')).to.equal(true);
|
||||
});
|
||||
|
||||
it('Works with mdx', async () => {
|
||||
const html = await fixture.readFile('/partials/docs/index.html');
|
||||
expect(html.startsWith('<h1')).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
|
@ -2967,6 +2967,15 @@ importers:
|
|||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/partials:
|
||||
dependencies:
|
||||
'@astrojs/mdx':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../integrations/mdx
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/postcss:
|
||||
dependencies:
|
||||
'@astrojs/solid-js':
|
||||
|
|
Loading…
Add table
Reference in a new issue