Skip to content

Commit

Permalink
Add display: contents for hydrated components (#1794)
Browse files Browse the repository at this point in the history
* Add display: contents for hydrated components

* Only serialize boolean attrs that are data attrs

* Adds a changeset
  • Loading branch information
matthewp authored Nov 11, 2021
1 parent 83be55d commit b958088
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-steaks-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Make astro-root be a display: contents element
2 changes: 1 addition & 1 deletion packages/astro/src/runtime/server/hydration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
22 changes: 17 additions & 5 deletions packages/astro/src/runtime/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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} />
Expand Down Expand Up @@ -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>');
}

Expand Down
6 changes: 3 additions & 3 deletions packages/astro/src/vite-plugin-build-html/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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));
}
Expand Down
9 changes: 9 additions & 0 deletions packages/astro/test/astro-styles-ssr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react';

export default function() {
return <div></div>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -33,6 +34,7 @@ import SvelteScoped from '../components/SvelteScoped.svelte';
<VueScoped />
<VueModules />
<SvelteScoped />
<ReactDynamic client:load />
</div>
</body>
</html>

0 comments on commit b958088

Please sign in to comment.