From 94d203ad767bc9c756d2848686cf3b87d0730c0b Mon Sep 17 00:00:00 2001 From: admirsaheta Date: Fri, 10 Jan 2025 14:30:47 +0100 Subject: [PATCH 1/6] fix:astro-mdx-component-rendering --- .vscode/settings.json | 2 +- packages/integrations/mdx/src/server.ts | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 97aeabec0f36..546fb7481d8f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,7 @@ "editor.defaultFormatter": "biomejs.biome" }, "[typescript]": { - "editor.defaultFormatter": "biomejs.biome" + "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[javascriptreact]": { "editor.defaultFormatter": "biomejs.biome" diff --git a/packages/integrations/mdx/src/server.ts b/packages/integrations/mdx/src/server.ts index 79934eb3229a..0c91dc3cb34f 100644 --- a/packages/integrations/mdx/src/server.ts +++ b/packages/integrations/mdx/src/server.ts @@ -1,6 +1,7 @@ -import type { NamedSSRLoadedRendererValue } from 'astro'; -import { AstroError } from 'astro/errors'; import { AstroJSX, jsx } from 'astro/jsx-runtime'; + +import { AstroError } from 'astro/errors'; +import type { NamedSSRLoadedRendererValue } from 'astro'; import { renderJSX } from 'astro/runtime/server/index.js'; const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); @@ -19,11 +20,14 @@ export async function check( slots[name] = value; } try { - const result = await Component({ ...props, ...slots, children }); - return result[AstroJSX]; - } catch (e) { + const vnode = jsx(Component, { ...props, ...slots, children }); + + const rendered = await renderJSX(null, vnode); + + return rendered[AstroJSX]; + } catch (e) { throwEnhancedErrorIfMdxComponent(e as Error, Component); - } + } return false; } From 9ef4bf22dff5fbea0b21fb7c624429d65b239334 Mon Sep 17 00:00:00 2001 From: admirsaheta Date: Fri, 10 Jan 2025 14:33:20 +0100 Subject: [PATCH 2/6] run:linter --- packages/integrations/mdx/src/server.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/integrations/mdx/src/server.ts b/packages/integrations/mdx/src/server.ts index 0c91dc3cb34f..96c931b8b328 100644 --- a/packages/integrations/mdx/src/server.ts +++ b/packages/integrations/mdx/src/server.ts @@ -1,7 +1,7 @@ import { AstroJSX, jsx } from 'astro/jsx-runtime'; -import { AstroError } from 'astro/errors'; import type { NamedSSRLoadedRendererValue } from 'astro'; +import { AstroError } from 'astro/errors'; import { renderJSX } from 'astro/runtime/server/index.js'; const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); @@ -21,13 +21,13 @@ export async function check( } try { const vnode = jsx(Component, { ...props, ...slots, children }); - + const rendered = await renderJSX(null, vnode); - + return rendered[AstroJSX]; - } catch (e) { + } catch (e) { throwEnhancedErrorIfMdxComponent(e as Error, Component); - } + } return false; } From befdddbe651de35c792972c361ed4e9d2ffcdccc Mon Sep 17 00:00:00 2001 From: admirsaheta Date: Fri, 10 Jan 2025 14:36:05 +0100 Subject: [PATCH 3/6] add:changeset --- .changeset/many-laws-add.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/many-laws-add.md diff --git a/.changeset/many-laws-add.md b/.changeset/many-laws-add.md new file mode 100644 index 000000000000..42c7e982e1d5 --- /dev/null +++ b/.changeset/many-laws-add.md @@ -0,0 +1,5 @@ +--- +'@astrojs/mdx': minor +--- + +Fixes the React Invalid Hook Call in MDX | React 19 From ddb17c778d0463db5e410303ab52f93e47f6c542 Mon Sep 17 00:00:00 2001 From: admirsaheta Date: Fri, 10 Jan 2025 14:37:48 +0100 Subject: [PATCH 4/6] revert:linter-on-accident --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 546fb7481d8f..97aeabec0f36 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,7 @@ "editor.defaultFormatter": "biomejs.biome" }, "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "biomejs.biome" }, "[javascriptreact]": { "editor.defaultFormatter": "biomejs.biome" From d2e7f998b79c201ece929902f25815a824f4ad57 Mon Sep 17 00:00:00 2001 From: admirsaheta Date: Fri, 10 Jan 2025 14:42:02 +0100 Subject: [PATCH 5/6] fix:pass-valid-sssresult --- packages/integrations/mdx/src/server.ts | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/integrations/mdx/src/server.ts b/packages/integrations/mdx/src/server.ts index 96c931b8b328..95e8f02eba55 100644 --- a/packages/integrations/mdx/src/server.ts +++ b/packages/integrations/mdx/src/server.ts @@ -1,7 +1,7 @@ import { AstroJSX, jsx } from 'astro/jsx-runtime'; -import type { NamedSSRLoadedRendererValue } from 'astro'; import { AstroError } from 'astro/errors'; +import type { NamedSSRLoadedRendererValue } from 'astro'; import { renderJSX } from 'astro/runtime/server/index.js'; const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); @@ -11,25 +11,29 @@ const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w export async function check( Component: any, props: any, - { default: children = null, ...slotted } = {}, -) { + { default: children = null, ...slotted } = {} + ) { if (typeof Component !== 'function') return false; + const slots: Record = {}; for (const [key, value] of Object.entries(slotted)) { - const name = slotName(key); - slots[name] = value; + const name = slotName(key); + slots[name] = value; } + try { - const vnode = jsx(Component, { ...props, ...slots, children }); - - const rendered = await renderJSX(null, vnode); - - return rendered[AstroJSX]; + const vnode = jsx(Component, { ...props, ...slots, children }); + + + const result = { styles: [], scripts: [], links: [] }; + const rendered = await renderJSX(result, vnode); + + return rendered[AstroJSX]; } catch (e) { - throwEnhancedErrorIfMdxComponent(e as Error, Component); + throwEnhancedErrorIfMdxComponent(e as Error, Component); } return false; -} + } export async function renderToStaticMarkup( this: any, From 260a840837c12e1da1c3d2d2e990dafa7a7b872e Mon Sep 17 00:00:00 2001 From: admirsaheta Date: Fri, 10 Jan 2025 14:50:51 +0100 Subject: [PATCH 6/6] add:mock-ssr-result --- packages/integrations/mdx/src/server.ts | 69 +++++++++++++++++++------ 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/packages/integrations/mdx/src/server.ts b/packages/integrations/mdx/src/server.ts index 95e8f02eba55..1a3de83316c0 100644 --- a/packages/integrations/mdx/src/server.ts +++ b/packages/integrations/mdx/src/server.ts @@ -1,39 +1,76 @@ import { AstroJSX, jsx } from 'astro/jsx-runtime'; -import { AstroError } from 'astro/errors'; import type { NamedSSRLoadedRendererValue } from 'astro'; +import { AstroError } from 'astro/errors'; import { renderJSX } from 'astro/runtime/server/index.js'; +import type { SSRResult } from '../../../astro/src/types/public/internal.js'; const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); +const mockSSRResult: SSRResult = { + cancelled: false, + base: '/', + styles: new Set(), + scripts: new Set(), + links: new Set(), + componentMetadata: new Map(), + inlinedScripts: new Map(), + createAstro: () => { + throw new Error('createAstro is not implemented in mock'); + }, + params: {}, + resolve: async (s: string) => s, + response: new Response(), + request: new Request('http://localhost'), + renderers: [], + clientDirectives: new Map(), + compressHTML: false, + partial: false, + pathname: '/', + cookies: undefined, + serverIslandNameMap: new Map(), + trailingSlash: 'ignore', + key: Promise.resolve( + crypto.subtle.generateKey({ name: 'HMAC', hash: 'SHA-256' }, true, ['sign', 'verify']), + ), + _metadata: { + propagators: new Set(), + hasHydrationScript: false, + rendererSpecificHydrationScripts: new Set(), + renderedScripts: new Set(), + hasDirectives: new Set(), + hasRenderedHead: false, + headInTree: false, + extraHead: [], + }, +}; + // NOTE: In practice, MDX components are always tagged with `__astro_tag_component__`, so the right renderer // is used directly, and this check is not often used to return true. export async function check( Component: any, props: any, - { default: children = null, ...slotted } = {} - ) { + { default: children = null, ...slotted } = {}, +) { if (typeof Component !== 'function') return false; - + const slots: Record = {}; for (const [key, value] of Object.entries(slotted)) { - const name = slotName(key); - slots[name] = value; + const name = slotName(key); + slots[name] = value; } - + try { - const vnode = jsx(Component, { ...props, ...slots, children }); - - - const result = { styles: [], scripts: [], links: [] }; - const rendered = await renderJSX(result, vnode); - - return rendered[AstroJSX]; + const vnode = jsx(Component, { ...props, ...slots, children }); + + const rendered = await renderJSX(mockSSRResult, vnode); + + return rendered[AstroJSX]; } catch (e) { - throwEnhancedErrorIfMdxComponent(e as Error, Component); + throwEnhancedErrorIfMdxComponent(e as Error, Component); } return false; - } +} export async function renderToStaticMarkup( this: any,