-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Simplified head injection * Make renderHead also yield an instruction * Add changeset * Add mdx test
- Loading branch information
Showing
20 changed files
with
411 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'astro': patch | ||
--- | ||
|
||
Ensure CSS injections properly when using multiple layouts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,15 @@ | ||
import type { SSRResult } from '../../../@types/astro'; | ||
import type { HydrationMetadata } from '../hydration.js'; | ||
|
||
export interface RenderInstruction { | ||
export type RenderDirectiveInstruction = { | ||
type: 'directive'; | ||
result: SSRResult; | ||
hydration: HydrationMetadata; | ||
}; | ||
|
||
export type RenderHeadInstruction = { | ||
type: 'head'; | ||
result: SSRResult; | ||
} | ||
|
||
export type RenderInstruction = RenderDirectiveInstruction | RenderHeadInstruction; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
import { expect } from 'chai'; | ||
|
||
import { | ||
createComponent, | ||
render, | ||
renderComponent, | ||
renderSlot, | ||
maybeRenderHead, | ||
renderHead, | ||
Fragment | ||
} from '../../../dist/runtime/server/index.js'; | ||
import { | ||
createBasicEnvironment, | ||
createRenderContext, | ||
renderPage, | ||
} from '../../../dist/core/render/index.js'; | ||
import { defaultLogging as logging } from '../../test-utils.js'; | ||
import * as cheerio from 'cheerio'; | ||
|
||
const createAstroModule = (AstroComponent) => ({ default: AstroComponent }); | ||
|
||
describe('core/render', () => { | ||
describe('Injected head contents', () => { | ||
let env; | ||
before(async () => { | ||
env = createBasicEnvironment({ | ||
logging, | ||
renderers: [], | ||
}); | ||
}); | ||
|
||
it('Multi-level layouts and head injection, with explicit head', async () => { | ||
const BaseLayout = createComponent((result, _props, slots) => { | ||
return render`<html> | ||
<head> | ||
${renderSlot(result, slots['head'])} | ||
${renderHead(result)} | ||
</head> | ||
${maybeRenderHead(result)} | ||
<body> | ||
${renderSlot(result, slots['default'])} | ||
</body> | ||
</html>`; | ||
}) | ||
|
||
const PageLayout = createComponent((result, _props, slots) => { | ||
return render`${renderComponent(result, 'Layout', BaseLayout, {}, { | ||
'default': () => render` | ||
${maybeRenderHead(result)} | ||
<main> | ||
${renderSlot(result, slots['default'])} | ||
</main> | ||
`, | ||
'head': () => render` | ||
${renderComponent(result, 'Fragment', Fragment, { slot: 'head' }, { | ||
'default': () => render`${renderSlot(result, slots['head'])}` | ||
})} | ||
` | ||
})} | ||
`; | ||
}); | ||
|
||
const Page = createComponent((result, _props) => { | ||
return render`${renderComponent(result, 'PageLayout', PageLayout, {}, { | ||
'default': () => render`${maybeRenderHead(result)}<div>hello world</div>`, | ||
'head': () => render` | ||
${renderComponent(result, 'Fragment', Fragment, {slot: 'head'}, { | ||
'default': () => render`<meta charset="utf-8">` | ||
})} | ||
` | ||
})}`; | ||
}); | ||
|
||
const ctx = createRenderContext({ | ||
request: new Request('http://example.com/'), | ||
links: [ | ||
{ name: 'link', props: {rel:'stylesheet', href:'/main.css'}, children: '' } | ||
] | ||
}); | ||
const PageModule = createAstroModule(Page); | ||
|
||
const response = await renderPage(PageModule, ctx, env); | ||
|
||
const html = await response.text(); | ||
const $ = cheerio.load(html); | ||
|
||
expect($('head link')).to.have.a.lengthOf(1); | ||
expect($('body link')).to.have.a.lengthOf(0); | ||
}); | ||
|
||
it('Multi-level layouts and head injection, without explicit head', async () => { | ||
const BaseLayout = createComponent((result, _props, slots) => { | ||
return render`<html> | ||
${renderSlot(result, slots['head'])} | ||
${maybeRenderHead(result)} | ||
<body> | ||
${renderSlot(result, slots['default'])} | ||
</body> | ||
</html>`; | ||
}) | ||
|
||
const PageLayout = createComponent((result, _props, slots) => { | ||
return render`${renderComponent(result, 'Layout', BaseLayout, {}, { | ||
'default': () => render` | ||
${maybeRenderHead(result)} | ||
<main> | ||
${renderSlot(result, slots['default'])} | ||
</main> | ||
`, | ||
'head': () => render` | ||
${renderComponent(result, 'Fragment', Fragment, { slot: 'head' }, { | ||
'default': () => render`${renderSlot(result, slots['head'])}` | ||
})} | ||
` | ||
})} | ||
`; | ||
}); | ||
|
||
const Page = createComponent((result, _props) => { | ||
return render`${renderComponent(result, 'PageLayout', PageLayout, {}, { | ||
'default': () => render`${maybeRenderHead(result)}<div>hello world</div>`, | ||
'head': () => render` | ||
${renderComponent(result, 'Fragment', Fragment, {slot: 'head'}, { | ||
'default': () => render`<meta charset="utf-8">` | ||
})} | ||
` | ||
})}`; | ||
}); | ||
|
||
const ctx = createRenderContext({ | ||
request: new Request('http://example.com/'), | ||
links: [ | ||
{ name: 'link', props: {rel:'stylesheet', href:'/main.css'}, children: '' } | ||
] | ||
}); | ||
const PageModule = createAstroModule(Page); | ||
|
||
const response = await renderPage(PageModule, ctx, env); | ||
|
||
const html = await response.text(); | ||
const $ = cheerio.load(html); | ||
|
||
expect($('head link')).to.have.a.lengthOf(1); | ||
expect($('body link')).to.have.a.lengthOf(0); | ||
}); | ||
|
||
it('Multi-level layouts and head injection, without any content in layouts', async () => { | ||
const BaseLayout = createComponent((result, _props, slots) => { | ||
return render`${renderSlot(result, slots['default'])}`; | ||
}) | ||
|
||
const PageLayout = createComponent((result, _props, slots) => { | ||
return render`${renderComponent(result, 'Layout', BaseLayout, {}, { | ||
'default': () => render`${renderSlot(result, slots['default'])} `, | ||
})} | ||
`; | ||
}); | ||
|
||
const Page = createComponent((result, _props) => { | ||
return render`${renderComponent(result, 'PageLayout', PageLayout, {}, { | ||
'default': () => render`${maybeRenderHead(result)}<div>hello world</div>`, | ||
})}`; | ||
}); | ||
|
||
const ctx = createRenderContext({ | ||
request: new Request('http://example.com/'), | ||
links: [ | ||
{ name: 'link', props: {rel:'stylesheet', href:'/main.css'}, children: '' } | ||
] | ||
}); | ||
const PageModule = createAstroModule(Page); | ||
|
||
const response = await renderPage(PageModule, ctx, env); | ||
|
||
const html = await response.text(); | ||
const $ = cheerio.load(html); | ||
|
||
expect($('link')).to.have.a.lengthOf(1); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.