diff options
7 files changed, 42 insertions, 9 deletions
diff --git a/.changeset/dull-steaks-dance.md b/.changeset/dull-steaks-dance.md new file mode 100644 index 000000000..3c95d998c --- /dev/null +++ b/.changeset/dull-steaks-dance.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Make astro-root be a display: contents element diff --git a/packages/astro/src/runtime/server/hydration.ts b/packages/astro/src/runtime/server/hydration.ts index dfd48abad..4a67825a9 100644 --- a/packages/astro/src/runtime/server/hydration.ts +++ b/packages/astro/src/runtime/server/hydration.ts @@ -112,7 +112,7 @@ export async function generateHydrateScript(scriptOptions: HydrateScriptOptions, `; const hydrationScript = { - props: { type: 'module' }, + props: { type: 'module', 'data-astro-component-hydration': true }, children: `import setup from 'astro/client/${hydrate}.js'; setup("${astroId}", {${metadata.hydrateArgs ? `value: ${JSON.stringify(metadata.hydrateArgs)}` : ''}}, async () => { ${hydrationSource} diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 5e191d406..a4db5c9fb 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -222,7 +222,12 @@ export function addAttribute(value: any, key: string) { return ` ${key.slice(0, -5)}="${toAttributeString(serializeListValue(value))}"`; } - return ` ${key}="${toAttributeString(value)}"`; + // Boolean only needs the key + if(value === true && key.startsWith('data-')) { + return ` ${key}`; + } else { + return ` ${key}="${toAttributeString(value)}"`; + } } // Adds support for `<Component {...value} /> @@ -278,14 +283,21 @@ export async function renderPage(result: SSRResult, Component: AstroComponentFac props: { ...style.props, 'astro-style': true }, }) ); + let needsHydrationStyles = false; const scripts = Array.from(result.scripts) .filter(uniqueElements) - .map((script, i) => - renderElement('script', { + .map((script, i) => { + if('data-astro-component-hydration' in script.props) { + needsHydrationStyles = true; + } + return renderElement('script', { ...script, props: { ...script.props, 'astro-script': result._metadata.pathname + '/script-' + i }, - }) - ); + }); + }); + if(needsHydrationStyles) { + styles.push(renderElement('style', { props: { 'astro-style': true },children: 'astro-root, astro-fragment { display: contents; }' })) + } return template.replace('</head>', styles.join('\n') + scripts.join('\n') + '</head>'); } diff --git a/packages/astro/src/vite-plugin-build-html/index.ts b/packages/astro/src/vite-plugin-build-html/index.ts index 262e00ca0..114dcbc48 100644 --- a/packages/astro/src/vite-plugin-build-html/index.ts +++ b/packages/astro/src/vite-plugin-build-html/index.ts @@ -7,7 +7,7 @@ import parse5 from 'parse5'; import srcsetParse from 'srcset-parse'; import * as npath from 'path'; import { promises as fs } from 'fs'; -import { getAttribute, getTagName, insertBefore, remove, createScript, createElement, setAttribute } from '@web/parse5-utils'; +import { getAttribute, hasAttribute, getTagName, insertBefore, remove, createScript, createElement, setAttribute } from '@web/parse5-utils'; import { addRollupInput } from './add-rollup-input.js'; import { findAssets, findInlineScripts, findInlineStyles, getTextContent, isStylesheetLink } from './extract-assets.js'; import { render as ssrRender } from '../core/ssr/index.js'; @@ -109,7 +109,7 @@ export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin { let styles = ''; for (const node of findInlineStyles(document)) { - if (getAttribute(node, 'astro-style')) { + if (hasAttribute(node, 'astro-style')) { styles += getTextContent(node); } } @@ -374,7 +374,7 @@ export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin { // Page styles for <style> usage, if not already appended via links. for (const style of findInlineStyles(document)) { - if (getAttribute(style, 'astro-style')) { + if (hasAttribute(style, 'astro-style')) { if (!pageCSSAdded) { pageCSSAdded = appendStyleChunksBefore(style, pathname, cssChunkMap.get(styleId)); } diff --git a/packages/astro/test/astro-styles-ssr.test.js b/packages/astro/test/astro-styles-ssr.test.js index 2412a7cd6..ddbd75f28 100644 --- a/packages/astro/test/astro-styles-ssr.test.js +++ b/packages/astro/test/astro-styles-ssr.test.js @@ -125,4 +125,13 @@ describe('Styles SSR', () => { expect($('#passed-in').attr('class')).to.match(/outer astro-[A-Z0-9]+ astro-[A-Z0-9]+/); }); + + it('Using hydrated components adds astro-root styles', async () => { + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + + const href = '/' + $('link').attr('href'); + const css = await fixture.readFile(href); + expect(css).to.include('display: contents;'); + }); }); diff --git a/packages/astro/test/fixtures/astro-styles-ssr/src/components/ReactDynamic.jsx b/packages/astro/test/fixtures/astro-styles-ssr/src/components/ReactDynamic.jsx new file mode 100644 index 000000000..14527edb4 --- /dev/null +++ b/packages/astro/test/fixtures/astro-styles-ssr/src/components/ReactDynamic.jsx @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function() { + return <div></div>; +}
\ No newline at end of file diff --git a/packages/astro/test/fixtures/astro-styles-ssr/src/pages/index.astro b/packages/astro/test/fixtures/astro-styles-ssr/src/pages/index.astro index 5135d7927..345d1b5bc 100644 --- a/packages/astro/test/fixtures/astro-styles-ssr/src/pages/index.astro +++ b/packages/astro/test/fixtures/astro-styles-ssr/src/pages/index.astro @@ -7,6 +7,7 @@ import VueCSS from '../components/VueCSS.vue'; import VueScoped from '../components/VueScoped.vue'; import VueModules from '../components/VueModules.vue'; import SvelteScoped from '../components/SvelteScoped.svelte'; +import ReactDynamic from '../components/ReactDynamic.jsx'; --- <html> @@ -33,6 +34,7 @@ import SvelteScoped from '../components/SvelteScoped.svelte'; <VueScoped /> <VueModules /> <SvelteScoped /> + <ReactDynamic client:load /> </div> </body> </html> |