diff --git a/.changeset/chilly-ads-roll.md b/.changeset/chilly-ads-roll.md deleted file mode 100644 index 8de509a18..000000000 --- a/.changeset/chilly-ads-roll.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/image': patch ---- - -`getPicture()` return object with the correct image type diff --git a/.changeset/clever-panthers-end.md b/.changeset/clever-panthers-end.md deleted file mode 100644 index ac52a0bfb..000000000 --- a/.changeset/clever-panthers-end.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Error overlay will now show the error's `cause` if available. diff --git a/.changeset/cold-maps-wash.md b/.changeset/cold-maps-wash.md new file mode 100644 index 000000000..406ce84f9 --- /dev/null +++ b/.changeset/cold-maps-wash.md @@ -0,0 +1,5 @@ +--- +'@astrojs/solid-js': patch +--- + +Bump vitefu for peerDep warning with Vite 4 diff --git a/.changeset/heavy-meals-complain.md b/.changeset/heavy-meals-complain.md deleted file mode 100644 index 2314150ff..000000000 --- a/.changeset/heavy-meals-complain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@astrojs/image': minor ---- - -Allow images from outside srcDir diff --git a/.changeset/wild-seas-happen.md b/.changeset/wild-seas-happen.md new file mode 100644 index 000000000..8db21e433 --- /dev/null +++ b/.changeset/wild-seas-happen.md @@ -0,0 +1,5 @@ +--- +'@astrojs/vercel': patch +--- + +Added second build step through esbuild, to allow framework defined build (vite build) and target defined bundling (esbuilt step) diff --git a/examples/basics/package.json b/examples/basics/package.json index d5efd9171..9dffd8bd0 100644 --- a/examples/basics/package.json +++ b/examples/basics/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" } } diff --git a/examples/blog/package.json b/examples/blog/package.json index 8ca5bb53e..87758e519 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -11,8 +11,8 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", - "@astrojs/mdx": "^0.15.2", + "astro": "^2.0.5", + "@astrojs/mdx": "^0.16.0", "@astrojs/rss": "^2.1.0", "@astrojs/sitemap": "^1.0.1" } diff --git a/examples/component/package.json b/examples/component/package.json index 5ec678dc5..85a9226a0 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -15,7 +15,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" }, "peerDependencies": { "astro": "^2.0.0-beta.0" diff --git a/examples/deno/package.json b/examples/deno/package.json index 806efc858..27413f456 100644 --- a/examples/deno/package.json +++ b/examples/deno/package.json @@ -10,7 +10,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" }, "devDependencies": { "@astrojs/deno": "^4.0.0" diff --git a/examples/docs/package.json b/examples/docs/package.json index 403ca3cdf..b04aa7adf 100644 --- a/examples/docs/package.json +++ b/examples/docs/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "preact": "^10.7.3", "react": "^18.1.0", "react-dom": "^18.1.0", diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index 408c5e5d8..1ce785196 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "alpinejs": "^3.10.2", "@astrojs/alpinejs": "^0.1.3", "@types/alpinejs": "^3.7.0" diff --git a/examples/framework-lit/package.json b/examples/framework-lit/package.json index 2d1e7c059..70c787dca 100644 --- a/examples/framework-lit/package.json +++ b/examples/framework-lit/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "lit": "^2.2.5", - "@astrojs/lit": "^1.1.1", + "@astrojs/lit": "^1.1.2", "@webcomponents/template-shadowroot": "^0.1.0" } } diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index fd8f0c9b0..5896c198a 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "preact": "^10.7.3", "react": "^18.1.0", "react-dom": "^18.1.0", diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index a5a7e699c..e93413c48 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "preact": "^10.7.3", "@astrojs/preact": "^2.0.1", "@preact/signals": "^1.1.0" diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index ecb27b24c..94cac639e 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "react": "^18.1.0", "react-dom": "^18.1.0", "@astrojs/react": "^2.0.2", diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index 74c75e4d4..81d474e6f 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "solid-js": "^1.4.3", "@astrojs/solid-js": "^2.0.1" } diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index d466823a9..fcc6ae58f 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -13,6 +13,6 @@ "dependencies": { "svelte": "^3.48.0", "@astrojs/svelte": "^2.0.1", - "astro": "^2.0.4" + "astro": "^2.0.5" } } diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index 670ccdf3b..f0085d7d4 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "vue": "^3.2.37", "@astrojs/vue": "^2.0.1" } diff --git a/examples/hackernews/package.json b/examples/hackernews/package.json index 1e6f00b80..b344dd59b 100644 --- a/examples/hackernews/package.json +++ b/examples/hackernews/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/node": "^5.0.1", - "astro": "^2.0.4" + "@astrojs/node": "^5.0.2", + "astro": "^2.0.5" } } diff --git a/examples/integration/package.json b/examples/integration/package.json index 28cf76a6c..f0139095a 100644 --- a/examples/integration/package.json +++ b/examples/integration/package.json @@ -15,7 +15,7 @@ ], "scripts": {}, "devDependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" }, "peerDependencies": { "astro": "^2.0.0-beta.0" diff --git a/examples/minimal/package.json b/examples/minimal/package.json index 5e6ab02bc..8c42d3011 100644 --- a/examples/minimal/package.json +++ b/examples/minimal/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" } } diff --git a/examples/non-html-pages/package.json b/examples/non-html-pages/package.json index 4c8daf7b8..12967c666 100644 --- a/examples/non-html-pages/package.json +++ b/examples/non-html-pages/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" } } diff --git a/examples/portfolio/package.json b/examples/portfolio/package.json index bc9bf951d..c7b52087e 100644 --- a/examples/portfolio/package.json +++ b/examples/portfolio/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" } } diff --git a/examples/ssr/package.json b/examples/ssr/package.json index e7e109cbc..6b876c0ce 100644 --- a/examples/ssr/package.json +++ b/examples/ssr/package.json @@ -12,10 +12,10 @@ "server": "node dist/server/entry.mjs" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "svelte": "^3.48.0", "@astrojs/svelte": "^2.0.1", - "@astrojs/node": "^5.0.1", + "@astrojs/node": "^5.0.2", "concurrently": "^7.2.1", "unocss": "^0.15.6", "vite-imagetools": "^4.0.4" diff --git a/examples/with-markdown-plugins/package.json b/examples/with-markdown-plugins/package.json index 48560e0f3..7f78949c7 100644 --- a/examples/with-markdown-plugins/package.json +++ b/examples/with-markdown-plugins/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "@astrojs/markdown-remark": "^2.0.1", "hast-util-select": "5.0.1", "rehype-autolink-headings": "^6.1.1", diff --git a/examples/with-markdown-shiki/package.json b/examples/with-markdown-shiki/package.json index c0e3a6c57..502397bf0 100644 --- a/examples/with-markdown-shiki/package.json +++ b/examples/with-markdown-shiki/package.json @@ -11,6 +11,6 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4" + "astro": "^2.0.5" } } diff --git a/examples/with-mdx/package.json b/examples/with-mdx/package.json index 36a84963c..d7d98fded 100644 --- a/examples/with-mdx/package.json +++ b/examples/with-mdx/package.json @@ -11,9 +11,9 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "preact": "^10.6.5", "@astrojs/preact": "^2.0.1", - "@astrojs/mdx": "^0.15.2" + "@astrojs/mdx": "^0.16.0" } } diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index 5eca1dce3..feb42be03 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "preact": "^10.7.3", "@astrojs/preact": "^2.0.1", "nanostores": "^0.5.12", diff --git a/examples/with-tailwindcss/package.json b/examples/with-tailwindcss/package.json index e37d6e9e1..5a7872712 100644 --- a/examples/with-tailwindcss/package.json +++ b/examples/with-tailwindcss/package.json @@ -11,10 +11,10 @@ "astro": "astro" }, "dependencies": { - "@astrojs/mdx": "^0.15.2", + "@astrojs/mdx": "^0.16.0", "@astrojs/tailwind": "^3.0.1", "@types/canvas-confetti": "^1.4.3", - "astro": "^2.0.4", + "astro": "^2.0.5", "autoprefixer": "^10.4.7", "canvas-confetti": "^1.5.1", "postcss": "^8.4.14", diff --git a/examples/with-vite-plugin-pwa/package.json b/examples/with-vite-plugin-pwa/package.json index f446c0971..7fe378a68 100644 --- a/examples/with-vite-plugin-pwa/package.json +++ b/examples/with-vite-plugin-pwa/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "vite-plugin-pwa": "0.11.11", "workbox-window": "^6.5.3" } diff --git a/examples/with-vitest/package.json b/examples/with-vitest/package.json index 2dfc73b98..921404bbf 100644 --- a/examples/with-vitest/package.json +++ b/examples/with-vitest/package.json @@ -12,7 +12,7 @@ "test": "vitest" }, "dependencies": { - "astro": "^2.0.4", + "astro": "^2.0.5", "vitest": "^0.20.3" } } diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index 485ea25b8..a301de2d6 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,17 @@ # astro +## 2.0.5 + +### Patch Changes + +- [#6052](https://github.com/withastro/astro/pull/6052) [`9793f19ec`](https://github.com/withastro/astro/commit/9793f19ecd4e64cbf3140454fe52aeee2c22c8c9) Thanks [@mayank99](https://github.com/mayank99)! - Error overlay will now show the error's `cause` if available. + +- [#6070](https://github.com/withastro/astro/pull/6070) [`f91615f5c`](https://github.com/withastro/astro/commit/f91615f5c04fde36f115dad9110dd75254efd61d) Thanks [@AirBorne04](https://github.com/AirBorne04)! - \* safe guard against TextEncode.encode(HTMLString) [errors on vercel edge] + + - safe guard against html.replace when html is undefined + +- [#6064](https://github.com/withastro/astro/pull/6064) [`2fb72c887`](https://github.com/withastro/astro/commit/2fb72c887f71c0a69ab512870d65b8c867774766) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Apply MDX `components` export when rendering as a content collection entry + ## 2.0.4 ### Patch Changes diff --git a/packages/astro/e2e/fixtures/lit-component/src/components/NonDeferredCounter.js b/packages/astro/e2e/fixtures/lit-component/src/components/NonDeferredCounter.js new file mode 100644 index 000000000..283d4063c --- /dev/null +++ b/packages/astro/e2e/fixtures/lit-component/src/components/NonDeferredCounter.js @@ -0,0 +1,35 @@ +import { LitElement, html } from 'lit'; + +export default class NonDeferredCounter extends LitElement { + static get properties() { + return { + count: { + type: Number, + // All set properties are reflected to attributes so its hydration is + // not deferred. + reflect: true, + }, + }; + } + + constructor() { + super(); + this.count = 0; + } + + increment() { + this.count++; + } + + render() { + return html` +
+

Count: ${this.count}

+ + +
+ `; + } +} + +customElements.define('non-deferred-counter', NonDeferredCounter); diff --git a/packages/astro/e2e/fixtures/lit-component/src/pages/index.astro b/packages/astro/e2e/fixtures/lit-component/src/pages/index.astro index ef86839d6..f15e832dc 100644 --- a/packages/astro/e2e/fixtures/lit-component/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/lit-component/src/pages/index.astro @@ -1,8 +1,9 @@ --- import MyCounter from '../components/Counter.js'; +import NonDeferredCounter from '../components/NonDeferredCounter.js'; const someProps = { - count: 0, + count: 10, }; --- @@ -15,6 +16,9 @@ const someProps = {

Hello, client:idle!

+ + +

Hello, client:load!

diff --git a/packages/astro/e2e/fixtures/lit-component/src/pages/media.astro b/packages/astro/e2e/fixtures/lit-component/src/pages/media.astro index a05d52863..69e1d7005 100644 --- a/packages/astro/e2e/fixtures/lit-component/src/pages/media.astro +++ b/packages/astro/e2e/fixtures/lit-component/src/pages/media.astro @@ -2,7 +2,7 @@ import MyCounter from '../components/Counter.js'; const someProps = { - count: 0, + count: 10, }; --- diff --git a/packages/astro/e2e/fixtures/lit-component/src/pages/solo.astro b/packages/astro/e2e/fixtures/lit-component/src/pages/solo.astro index 1d2745e47..c9dfe0ba0 100644 --- a/packages/astro/e2e/fixtures/lit-component/src/pages/solo.astro +++ b/packages/astro/e2e/fixtures/lit-component/src/pages/solo.astro @@ -2,7 +2,7 @@ import MyCounter from '../components/Counter.js'; const someProps = { - count: 0, + count: 10, }; --- diff --git a/packages/astro/e2e/lit-component.test.js b/packages/astro/e2e/lit-component.test.js index 6603d5b80..85af631b9 100644 --- a/packages/astro/e2e/lit-component.test.js +++ b/packages/astro/e2e/lit-component.test.js @@ -32,12 +32,25 @@ test.describe('Lit components', () => { await expect(counter).toHaveCount(1); const count = counter.locator('p'); - await expect(count, 'initial count is 0').toHaveText('Count: 0'); + await expect(count, 'initial count is 10').toHaveText('Count: 10'); const inc = counter.locator('button'); await inc.click(); - await expect(count, 'count incremented by 1').toHaveText('Count: 1'); + await expect(count, 'count incremented by 1').toHaveText('Count: 11'); + }); + + t('non-deferred attribute serialization', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + + const counter = page.locator('#non-deferred'); + const count = counter.locator('p'); + await expect(count, 'initial count is 10').toHaveText('Count: 10'); + + const inc = counter.locator('button'); + await inc.click(); + + await expect(count, 'count incremented by 1').toHaveText('Count: 11'); }); t('client:load', async ({ page, astro }) => { @@ -47,12 +60,12 @@ test.describe('Lit components', () => { await expect(counter, 'component is visible').toBeVisible(); const count = counter.locator('p'); - await expect(count, 'initial count is 0').toHaveText('Count: 0'); + await expect(count, 'initial count is 10').toHaveText('Count: 10'); const inc = counter.locator('button'); await inc.click(); - await expect(count, 'count incremented by 1').toHaveText('Count: 1'); + await expect(count, 'count incremented by 1').toHaveText('Count: 11'); }); t('client:visible', async ({ page, astro }) => { @@ -64,12 +77,12 @@ test.describe('Lit components', () => { await expect(counter, 'component is visible').toBeVisible(); const count = counter.locator('p'); - await expect(count, 'initial count is 0').toHaveText('Count: 0'); + await expect(count, 'initial count is 10').toHaveText('Count: 10'); const inc = counter.locator('button'); await inc.click(); - await expect(count, 'count incremented by 1').toHaveText('Count: 1'); + await expect(count, 'count incremented by 1').toHaveText('Count: 11'); }); t('client:media', async ({ page, astro }) => { @@ -79,18 +92,18 @@ test.describe('Lit components', () => { await expect(counter, 'component is visible').toBeVisible(); const count = counter.locator('p'); - await expect(count, 'initial count is 0').toHaveText('Count: 0'); + await expect(count, 'initial count is 10').toHaveText('Count: 10'); const inc = counter.locator('button'); await inc.click(); - await expect(count, 'component not hydrated yet').toHaveText('Count: 0'); + await expect(count, 'component not hydrated yet').toHaveText('Count: 10'); // Reset the viewport to hydrate the component (max-width: 50rem) await page.setViewportSize({ width: 414, height: 1124 }); await inc.click(); - await expect(count, 'count incremented by 1').toHaveText('Count: 1'); + await expect(count, 'count incremented by 1').toHaveText('Count: 11'); }); t.skip('HMR', async ({ page, astro }) => { diff --git a/packages/astro/package.json b/packages/astro/package.json index 3eaffc937..9936aa8ba 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "astro", - "version": "2.0.4", + "version": "2.0.5", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "type": "module", "author": "withastro", diff --git a/packages/astro/src/content/internal.ts b/packages/astro/src/content/internal.ts index 2b8f8ba6f..04280166f 100644 --- a/packages/astro/src/content/internal.ts +++ b/packages/astro/src/content/internal.ts @@ -1,3 +1,4 @@ +import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { prependForwardSlash } from '../core/path.js'; import { @@ -120,21 +121,32 @@ async function render({ id: string; collectionToRenderEntryMap: CollectionToEntryMap; }) { - const lazyImport = collectionToRenderEntryMap[collection]?.[id]; - if (!lazyImport) throw new Error(`${String(collection)} → ${String(id)} does not exist.`); + const UnexpectedRenderError = new AstroError({ + ...AstroErrorData.UnknownContentCollectionError, + message: `Unexpected error while rendering ${String(collection)} → ${String(id)}.`, + }); - const mod = await lazyImport(); + const lazyImport = collectionToRenderEntryMap[collection]?.[id]; + if (typeof lazyImport !== 'function') throw UnexpectedRenderError; + + const baseMod = await lazyImport(); + if (baseMod == null || typeof baseMod !== 'object') throw UnexpectedRenderError; + + const { collectedStyles, collectedLinks, collectedScripts, getMod } = baseMod; + if (typeof getMod !== 'function') throw UnexpectedRenderError; + const mod = await getMod(); + if (mod == null || typeof mod !== 'object') throw UnexpectedRenderError; const Content = createComponent({ - factory(result, props, slots) { + factory(result, baseProps, slots) { let styles = '', links = '', scripts = ''; - if (Array.isArray(mod?.collectedStyles)) { - styles = mod.collectedStyles.map((style: any) => renderStyleElement(style)).join(''); + if (Array.isArray(collectedStyles)) { + styles = collectedStyles.map((style: any) => renderStyleElement(style)).join(''); } - if (Array.isArray(mod?.collectedLinks)) { - links = mod.collectedLinks + if (Array.isArray(collectedLinks)) { + links = collectedLinks .map((link: any) => { return renderUniqueStylesheet(result, { href: prependForwardSlash(link), @@ -142,8 +154,17 @@ async function render({ }) .join(''); } - if (Array.isArray(mod?.collectedScripts)) { - scripts = mod.collectedScripts.map((script: any) => renderScriptElement(script)).join(''); + if (Array.isArray(collectedScripts)) { + scripts = collectedScripts.map((script: any) => renderScriptElement(script)).join(''); + } + + let props = baseProps; + // Auto-apply MDX components export + if (id.endsWith('mdx')) { + props = { + components: mod.components ?? {}, + ...baseProps, + }; } return createHeadAndContent( diff --git a/packages/astro/src/content/vite-plugin-content-assets.ts b/packages/astro/src/content/vite-plugin-content-assets.ts index 54b84380d..fd73caf47 100644 --- a/packages/astro/src/content/vite-plugin-content-assets.ts +++ b/packages/astro/src/content/vite-plugin-content-assets.ts @@ -36,7 +36,9 @@ export function astroContentAssetPropagationPlugin({ mode }: { mode: string }): if (isPropagatedAsset(id)) { const basePath = id.split('?')[0]; const code = ` - export { Content, getHeadings, frontmatter } from ${JSON.stringify(basePath)}; + export async function getMod() { + return import(${JSON.stringify(basePath)}); + } export const collectedLinks = ${JSON.stringify(LINKS_PLACEHOLDER)}; export const collectedStyles = ${JSON.stringify(STYLES_PLACEHOLDER)}; export const collectedScripts = ${JSON.stringify(SCRIPTS_PLACEHOLDER)}; diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 498a612dc..83cc92e8f 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -419,7 +419,7 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati * @docs * @message * **Example error messages:**
- * InvalidComponentArgs: Invalid arguments passed to component. + * InvalidComponentArgs: Invalid arguments passed to `` component. * @description * Astro components cannot be rendered manually via a function call, such as `Component()` or `{items.map(Component)}`. Prefer the component syntax `` or `{items.map(item => )}`. */ @@ -635,6 +635,7 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati }, /** * @docs + * @message `COLLECTION_NAME` → `ENTRY_ID` has an invalid slug. `slug` must be a string. * @see * - [The reserved entry `slug` field](https://docs.astro.build/en/guides/content-collections/) * @description @@ -652,6 +653,7 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati }, /** * @docs + * @message A content collection schema should not contain `slug` since it is reserved for slug generation. Remove this from your `COLLECTION_NAME` collection schema. * @see * - [The reserved entry `slug` field](https://docs.astro.build/en/guides/content-collections/) * @description diff --git a/packages/astro/src/runtime/server/render/common.ts b/packages/astro/src/runtime/server/render/common.ts index 9b1aa1453..def7dedd3 100644 --- a/packages/astro/src/runtime/server/render/common.ts +++ b/packages/astro/src/runtime/server/render/common.ts @@ -93,5 +93,7 @@ export function chunkToByteArray( if (chunk instanceof Uint8Array) { return chunk as Uint8Array; } - return encoder.encode(stringifyChunk(result, chunk)); + // stringify chunk might return a HTMLString + let stringified = stringifyChunk(result, chunk); + return encoder.encode(stringified.toString()); } diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts index b6a6576f1..034e79667 100644 --- a/packages/astro/src/runtime/server/render/component.ts +++ b/packages/astro/src/runtime/server/render/component.ts @@ -261,8 +261,10 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr if (isPage || renderer?.name === 'astro:jsx') { yield html; - } else { + } else if (html && html.length > 0) { yield markHTMLString(html.replace(/\<\/?astro-slot\>/g, '')); + } else { + yield ''; } })(); } diff --git a/packages/astro/test/content-collections-render.test.js b/packages/astro/test/content-collections-render.test.js index 92015393c..da14a4765 100644 --- a/packages/astro/test/content-collections-render.test.js +++ b/packages/astro/test/content-collections-render.test.js @@ -71,6 +71,15 @@ describe('Content Collections - render()', () => { '`WithScripts.astro` hoisted script included unexpectedly.' ).to.be.undefined; }); + + it('Applies MDX components export', async () => { + const html = await fixture.readFile('/launch-week-components-export/index.html'); + const $ = cheerio.load(html); + + const h2 = $('h2'); + expect(h2).to.have.a.lengthOf(1); + expect(h2.attr('data-components-export-applied')).to.equal('true'); + }); }); describe('Build - SSR', () => { @@ -110,6 +119,18 @@ describe('Content Collections - render()', () => { // Includes styles expect($('link[rel=stylesheet]')).to.have.a.lengthOf(0); }); + + it('Applies MDX components export', async () => { + const app = await fixture.loadTestAdapterApp(); + const request = new Request('http://example.com/launch-week-components-export'); + const response = await app.render(request); + const html = await response.text(); + const $ = cheerio.load(html); + + const h2 = $('h2'); + expect(h2).to.have.a.lengthOf(1); + expect(h2.attr('data-components-export-applied')).to.equal('true'); + }); }); describe('Dev - SSG', () => { @@ -162,5 +183,17 @@ describe('Content Collections - render()', () => { // Includes inline script expect($('script[data-is-inline]')).to.have.a.lengthOf(1); }); + + it('Applies MDX components export', async () => { + const response = await fixture.fetch('/launch-week-components-export', { method: 'GET' }); + expect(response.status).to.equal(200); + + const html = await response.text(); + const $ = cheerio.load(html); + + const h2 = $('h2'); + expect(h2).to.have.a.lengthOf(1); + expect(h2.attr('data-components-export-applied')).to.equal('true'); + }); }); }); diff --git a/packages/astro/test/custom-elements.test.js b/packages/astro/test/custom-elements.test.js index b66c648a4..51e8ece34 100644 --- a/packages/astro/test/custom-elements.test.js +++ b/packages/astro/test/custom-elements.test.js @@ -23,7 +23,7 @@ describe('Custom Elements', () => { expect($('my-element')).to.have.lengthOf(1); // test 2: shadow rendered - expect($('my-element template[shadowroot=open]')).to.have.lengthOf(1); + expect($('my-element template[shadowroot=open][shadowrootmode=open]')).to.have.lengthOf(1); }); it('Works with exported tagName', async () => { @@ -34,7 +34,7 @@ describe('Custom Elements', () => { expect($('my-element')).to.have.lengthOf(1); // test 2: shadow rendered - expect($('my-element template[shadowroot=open]')).to.have.lengthOf(1); + expect($('my-element template[shadowroot=open][shadowrootmode=open]')).to.have.lengthOf(1); }); it.skip('Hydration works with exported tagName', async () => { @@ -46,7 +46,7 @@ describe('Custom Elements', () => { expect($('my-element')).to.have.lengthOf(1); // test 2: shadow rendered - expect($('my-element template[shadowroot=open]')).to.have.lengthOf(1); + expect($('my-element template[shadowroot=open][shadowrootmode=open]')).to.have.lengthOf(1); // Hydration // test 3: Component and polyfill scripts bundled separately diff --git a/packages/astro/test/fixtures/content/src/components/H2.astro b/packages/astro/test/fixtures/content/src/components/H2.astro new file mode 100644 index 000000000..d1ad359c2 --- /dev/null +++ b/packages/astro/test/fixtures/content/src/components/H2.astro @@ -0,0 +1,4 @@ +--- +--- + +

diff --git a/packages/astro/test/fixtures/content/src/content/blog/promo/launch-week-components-export.mdx b/packages/astro/test/fixtures/content/src/content/blog/promo/launch-week-components-export.mdx new file mode 100644 index 000000000..40012b8ef --- /dev/null +++ b/packages/astro/test/fixtures/content/src/content/blog/promo/launch-week-components-export.mdx @@ -0,0 +1,18 @@ +--- +title: 'Launch week!' +description: 'Join us for the exciting launch of SPACE BLOG' +publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)' +tags: ['announcement'] +--- + +import H2 from '../../../components/H2.astro'; + +export const components = { h2: H2 }; + +Join us for the space blog launch! + +## Details + +- THIS THURSDAY +- Houston, TX +- Dress code: **interstellar casual** ✨ diff --git a/packages/astro/test/fixtures/content/src/pages/launch-week-components-export.astro b/packages/astro/test/fixtures/content/src/pages/launch-week-components-export.astro new file mode 100644 index 000000000..463e65191 --- /dev/null +++ b/packages/astro/test/fixtures/content/src/pages/launch-week-components-export.astro @@ -0,0 +1,14 @@ +--- +import { getEntryBySlug } from 'astro:content'; + +const entry = await getEntryBySlug('blog', 'promo/launch-week-components-export'); +const { Content } = await entry.render(); +--- + + + Launch Week + + + + + diff --git a/packages/astro/test/fixtures/custom-elements/my-component-lib/server.js b/packages/astro/test/fixtures/custom-elements/my-component-lib/server.js index 7e36a26fd..688923159 100644 --- a/packages/astro/test/fixtures/custom-elements/my-component-lib/server.js +++ b/packages/astro/test/fixtures/custom-elements/my-component-lib/server.js @@ -18,7 +18,7 @@ function renderToStaticMarkup(component, props, innerHTML) { const Component = getConstructor(component); const el = new Component(); el.connectedCallback(); - const html = `<${el.localName}>${el.innerHTML}` + const html = `<${el.localName}>${el.innerHTML}` return { html }; diff --git a/packages/astro/test/fixtures/lit-element/src/components/non-deferred-element.ts b/packages/astro/test/fixtures/lit-element/src/components/non-deferred-element.ts new file mode 100644 index 000000000..0cd36576b --- /dev/null +++ b/packages/astro/test/fixtures/lit-element/src/components/non-deferred-element.ts @@ -0,0 +1,23 @@ +import { LitElement, html } from 'lit'; +import { property, customElement } from 'lit/decorators.js'; + +@customElement('non-deferred-counter') +export class NonDeferredCounter extends LitElement { + // All set properties are reflected to attributes so its hydration is not + // hydration-deferred should always be set. + @property({ type: Number, reflect: true }) count = 0; + + increment() { + this.count++; + } + + render() { + return html` +
+

Count: ${this.count}

+ + +
+ `; + } +} diff --git a/packages/astro/test/fixtures/lit-element/src/pages/index.astro b/packages/astro/test/fixtures/lit-element/src/pages/index.astro index 408360157..394885fca 100644 --- a/packages/astro/test/fixtures/lit-element/src/pages/index.astro +++ b/packages/astro/test/fixtures/lit-element/src/pages/index.astro @@ -1,18 +1,25 @@ --- import {MyElement} from '../components/my-element.js'; +import {NonDeferredCounter} from '../components/non-deferred-element.js'; --- - LitElements + LitElements - - + + + + diff --git a/packages/astro/test/lit-element.test.js b/packages/astro/test/lit-element.test.js index a74fb0fc5..9512909d8 100644 --- a/packages/astro/test/lit-element.test.js +++ b/packages/astro/test/lit-element.test.js @@ -30,36 +30,57 @@ describe('LitElement test', function () { const $ = cheerio.load(html); // test 1: attributes rendered – non reactive properties - expect($('my-element').attr('foo')).to.equal('bar'); + expect($('#default').attr('foo')).to.equal('bar'); // test 2: shadow rendered - expect($('my-element').html()).to.include(`
Testing...
`); + expect($('#default').html()).to.include(`
Testing...
`); // test 3: string reactive property set - expect(stripExpressionMarkers($('my-element').html())).to.include( + expect(stripExpressionMarkers($('#default').html())).to.include( `
initialized
` ); // test 4: boolean reactive property correctly set // Lit will equate to true because it uses // this.hasAttribute to determine its value - expect(stripExpressionMarkers($('my-element').html())).to.include(`
B
`); + expect(stripExpressionMarkers($('#default').html())).to.include(`
B
`); // test 5: object reactive property set // by default objects will be stringified to [object Object] - expect(stripExpressionMarkers($('my-element').html())).to.include( - `
data: 1
` - ); + expect(stripExpressionMarkers($('#default').html())).to.include(`
data: 1
`); // test 6: reactive properties are not rendered as attributes - expect($('my-element').attr('obj')).to.equal(undefined); - expect($('my-element').attr('bool')).to.equal(undefined); - expect($('my-element').attr('str')).to.equal(undefined); + expect($('#default').attr('obj')).to.equal(undefined); + expect($('#default').attr('bool')).to.equal(undefined); + expect($('#default').attr('str')).to.equal(undefined); // test 7: reflected reactive props are rendered as attributes - expect($('my-element').attr('reflectedbool')).to.equal(''); - expect($('my-element').attr('reflected-str')).to.equal('default reflected string'); - expect($('my-element').attr('reflected-str-prop')).to.equal('initialized reflected'); + expect($('#default').attr('reflectedbool')).to.equal(''); + expect($('#default').attr('reflected-str')).to.equal('default reflected string'); + expect($('#default').attr('reflected-str-prop')).to.equal('initialized reflected'); + }); + + it('Sets defer-hydration on element only when necessary', async () => { + // @lit-labs/ssr/ requires Node 13.9 or higher + if (NODE_VERSION < 13.9) { + return; + } + const html = await fixture.readFile('/index.html'); + const $ = cheerio.load(html); + + // test 1: reflected reactive props are rendered as attributes + expect($('#non-deferred').attr('count')).to.equal('10'); + + // test 2: non-reactive props are set as attributes + expect($('#non-deferred').attr('foo')).to.equal('bar'); + + // test 3: components with only reflected reactive props set are not + // deferred because their state can be completely serialized via attributes + expect($('#non-deferred').attr('defer-hydration')).to.equal(undefined); + + // test 4: components with non-reflected reactive props set are deferred because + // their state needs to be synced with the server on the client. + expect($('#default').attr('defer-hydration')).to.equal(''); }); it('Correctly passes child slots', async () => { @@ -74,7 +95,7 @@ describe('LitElement test', function () { const $slottedMyElement = $('#slotted'); const $slottedSlottedMyElement = $('#slotted-slotted'); - expect($('my-element').length).to.equal(3); + expect($('#default').length).to.equal(3); // Root my-element expect($rootMyElement.children('.default').length).to.equal(2); diff --git a/packages/integrations/cloudflare/package.json b/packages/integrations/cloudflare/package.json index ca9e34dfb..a2e8ad1da 100644 --- a/packages/integrations/cloudflare/package.json +++ b/packages/integrations/cloudflare/package.json @@ -38,7 +38,7 @@ "tiny-glob": "^0.2.9" }, "peerDependencies": { - "astro": "workspace:^2.0.4" + "astro": "workspace:^2.0.5" }, "devDependencies": { "astro": "workspace:*", diff --git a/packages/integrations/deno/package.json b/packages/integrations/deno/package.json index 2a2b96d60..528bc266f 100644 --- a/packages/integrations/deno/package.json +++ b/packages/integrations/deno/package.json @@ -32,7 +32,7 @@ "esbuild": "^0.15.18" }, "peerDependencies": { - "astro": "workspace:^2.0.4" + "astro": "workspace:^2.0.5" }, "devDependencies": { "astro": "workspace:*", diff --git a/packages/integrations/image/CHANGELOG.md b/packages/integrations/image/CHANGELOG.md index a085abcd7..90cff675a 100644 --- a/packages/integrations/image/CHANGELOG.md +++ b/packages/integrations/image/CHANGELOG.md @@ -1,5 +1,18 @@ # @astrojs/image +## 0.14.0 + +### Minor Changes + +- [#5932](https://github.com/withastro/astro/pull/5932) [`b3e65991f`](https://github.com/withastro/astro/commit/b3e65991f731f5320ba5826c731934a8e8482493) Thanks [@rasendubi](https://github.com/rasendubi)! - Allow images from outside srcDir + +### Patch Changes + +- [#5894](https://github.com/withastro/astro/pull/5894) [`ca91976ed`](https://github.com/withastro/astro/commit/ca91976edbfd34adbb31096516a266f31d8f6216) Thanks [@ralacerda](https://github.com/ralacerda)! - `getPicture()` return object with the correct image type + +- Updated dependencies [[`9793f19ec`](https://github.com/withastro/astro/commit/9793f19ecd4e64cbf3140454fe52aeee2c22c8c9), [`f91615f5c`](https://github.com/withastro/astro/commit/f91615f5c04fde36f115dad9110dd75254efd61d), [`2fb72c887`](https://github.com/withastro/astro/commit/2fb72c887f71c0a69ab512870d65b8c867774766)]: + - astro@2.0.5 + ## 0.13.1 ### Patch Changes diff --git a/packages/integrations/image/README.md b/packages/integrations/image/README.md index 213d9d3bb..89fdbaba8 100644 --- a/packages/integrations/image/README.md +++ b/packages/integrations/image/README.md @@ -259,7 +259,7 @@ color representation with 3 or 6 hexadecimal characters in the form `#123[abc]`, **Default:** `'cover'`

-> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. +> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. Read more about [how `sharp` resizes images](https://sharp.pixelplumbing.com/api-resize). How the image should be resized to fit both `height` and `width`. @@ -271,7 +271,7 @@ How the image should be resized to fit both `height` and `width`. **Default:** `'centre'`

-> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. +> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. Read more about [how `sharp` resizes images](https://sharp.pixelplumbing.com/api-resize). Position of the crop when fit is `cover` or `contain`. @@ -333,7 +333,7 @@ The list of sizes that should be built for responsive images. This is combined w ```astro // Builds three images: 400x400, 800x800, and 1200x1200 - + ``` #### aspectRatio @@ -392,7 +392,7 @@ color representation with 3 or 6 hexadecimal characters in the form `#123[abc]`, **Default:** `'cover'`

-> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. +> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. Read more about [how `sharp` resizes images](https://sharp.pixelplumbing.com/api-resize). How the image should be resized to fit both `height` and `width`. @@ -406,7 +406,7 @@ How the image should be resized to fit both `height` and `width`. **Default:** `'centre'`

-> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. +> This is not supported by the default Squoosh service. See the [installation section](#installing-sharp-optional) for details on using the `sharp` service instead. Read more about [how `sharp` resizes images](https://sharp.pixelplumbing.com/api-resize). Position of the crop when fit is `cover` or `contain`. @@ -422,7 +422,10 @@ This can be helpful if you need to add preload links to a page's ``. --- import { getImage } from '@astrojs/image'; -const { src } = await getImage({src: '../assets/hero.png'}); +const { src } = await getImage({ + src: import('../assets/hero.png'), + alt: "My hero image" + }); --- diff --git a/packages/integrations/image/package.json b/packages/integrations/image/package.json index 1c82a2beb..6c84fdcad 100644 --- a/packages/integrations/image/package.json +++ b/packages/integrations/image/package.json @@ -1,7 +1,7 @@ { "name": "@astrojs/image", "description": "Load and transform images in your Astro site.", - "version": "0.13.1", + "version": "0.14.0", "type": "module", "types": "./dist/index.d.ts", "author": "withastro", @@ -63,7 +63,7 @@ "vite": "^4.0.3" }, "peerDependencies": { - "astro": "workspace:^2.0.4", + "astro": "workspace:^2.0.5", "sharp": ">=0.31.0" }, "peerDependenciesMeta": { diff --git a/packages/integrations/lit/CHANGELOG.md b/packages/integrations/lit/CHANGELOG.md index bb7b90fe0..8a58af5ff 100644 --- a/packages/integrations/lit/CHANGELOG.md +++ b/packages/integrations/lit/CHANGELOG.md @@ -1,5 +1,13 @@ # @astrojs/lit +## 1.1.2 + +### Patch Changes + +- [#6080](https://github.com/withastro/astro/pull/6080) [`0db220415`](https://github.com/withastro/astro/commit/0db22041531d981a813a07f4c4e00cfb7ebddd51) Thanks [@e111077](https://github.com/e111077)! - Fixes Lit hydration not having the same reactive values as server (losing state upon hydration) + +- [#6055](https://github.com/withastro/astro/pull/6055) [`2567aa48b`](https://github.com/withastro/astro/commit/2567aa48bba8751cf7e10429555f1e85830c9169) Thanks [@e111077](https://github.com/e111077)! - Add forwards compatibility for streaming Declarative Shadow DOM + ## 1.1.1 ### Patch Changes diff --git a/packages/integrations/lit/client-shim.js b/packages/integrations/lit/client-shim.js index ca97b92cc..a798dba4d 100644 --- a/packages/integrations/lit/client-shim.js +++ b/packages/integrations/lit/client-shim.js @@ -8,9 +8,13 @@ async function polyfill() { } const polyfillCheckEl = new DOMParser() - .parseFromString(`

`, 'text/html', { - includeShadowRoots: true, - }) + .parseFromString( + `

`, + 'text/html', + { + includeShadowRoots: true, + } + ) .querySelector('p'); if (!polyfillCheckEl || !polyfillCheckEl.shadowRoot) { diff --git a/packages/integrations/lit/client-shim.min.js b/packages/integrations/lit/client-shim.min.js index afae053ac..2e3d07ae7 100644 --- a/packages/integrations/lit/client-shim.min.js +++ b/packages/integrations/lit/client-shim.min.js @@ -8,7 +8,7 @@ var b = (t, n) => { function s() { if (d === void 0) { let t = document.createElement('div'); - (t.innerHTML = '
'), + (t.innerHTML = '
'), (d = !!t.firstElementChild.shadowRoot); } return d; @@ -80,8 +80,12 @@ async function g() { window.addEventListener('DOMContentLoaded', () => t(document.body), { once: true }); } var x = new DOMParser() - .parseFromString('

', 'text/html', { - includeShadowRoots: !0, - }) + .parseFromString( + '

', + 'text/html', + { + includeShadowRoots: !0, + } + ) .querySelector('p'); (!x || !x.shadowRoot) && g(); diff --git a/packages/integrations/lit/package.json b/packages/integrations/lit/package.json index ac0a8608c..6d5f375f9 100644 --- a/packages/integrations/lit/package.json +++ b/packages/integrations/lit/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/lit", - "version": "1.1.1", + "version": "1.1.2", "description": "Use Lit components within Astro", "type": "module", "types": "./dist/index.d.ts", @@ -23,6 +23,7 @@ ".": "./dist/index.js", "./server.js": "./server.js", "./client-shim.js": "./client-shim.js", + "./dist/client.js": "./dist/client.js", "./hydration-support.js": "./hydration-support.js", "./package.json": "./package.json" }, diff --git a/packages/integrations/lit/server.js b/packages/integrations/lit/server.js index 83737c183..da571466f 100644 --- a/packages/integrations/lit/server.js +++ b/packages/integrations/lit/server.js @@ -36,10 +36,18 @@ function* render(Component, attrs, slots) { // LitElementRenderer creates a new element instance, so copy over. const Ctr = getCustomElementConstructor(tagName); + let shouldDeferHydration = false; + if (attrs) { for (let [name, value] of Object.entries(attrs)) { - // check if this is a reactive property - if (name in Ctr.prototype) { + const isReactiveProperty = name in Ctr.prototype; + const isReflectedReactiveProperty = Ctr.elementProperties.get(name)?.reflect; + + // Only defer hydration if we are setting a reactive property that cannot + // be reflected / serialized as a property. + shouldDeferHydration ||= isReactiveProperty && !isReflectedReactiveProperty; + + if (isReactiveProperty) { instance.setProperty(name, value); } else { instance.setAttribute(name, value); @@ -49,12 +57,12 @@ function* render(Component, attrs, slots) { instance.connectedCallback(); - yield `<${tagName}`; + yield `<${tagName}${shouldDeferHydration ? ' defer-hydration' : ''}`; yield* instance.renderAttributes(); yield `>`; const shadowContents = instance.renderShadow({}); if (shadowContents !== undefined) { - yield '