summaryrefslogtreecommitdiff
path: root/packages/integrations/mdx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/mdx')
-rw-r--r--packages/integrations/mdx/src/astro-data-utils.ts2
-rw-r--r--packages/integrations/mdx/src/index.ts19
-rw-r--r--packages/integrations/mdx/test/fixtures/mdx-component/src/pages/glob.astro11
-rw-r--r--packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/layouts/Base.astro8
-rw-r--r--packages/integrations/mdx/test/mdx-component.test.js56
-rw-r--r--packages/integrations/mdx/test/mdx-frontmatter.test.js11
6 files changed, 104 insertions, 3 deletions
diff --git a/packages/integrations/mdx/src/astro-data-utils.ts b/packages/integrations/mdx/src/astro-data-utils.ts
index 0bc375c27..f3d04e431 100644
--- a/packages/integrations/mdx/src/astro-data-utils.ts
+++ b/packages/integrations/mdx/src/astro-data-utils.ts
@@ -28,6 +28,8 @@ export function rehypeApplyFrontmatterExport(pageFrontmatter: Record<string, any
export default function ({ children }) {
const { layout, ...content } = frontmatter;
+ content.file = file;
+ content.url = url;
content.astro = {};
Object.defineProperty(content.astro, 'headings', {
get() {
diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts
index f92a10a53..17fe0cd74 100644
--- a/packages/integrations/mdx/src/index.ts
+++ b/packages/integrations/mdx/src/index.ts
@@ -26,6 +26,12 @@ const DEFAULT_REMARK_PLUGINS: MdxRollupPluginOptions['remarkPlugins'] = [
];
const DEFAULT_REHYPE_PLUGINS: MdxRollupPluginOptions['rehypePlugins'] = [];
+const RAW_CONTENT_ERROR =
+ 'MDX does not support rawContent()! If you need to read the Markdown contents to calculate values (ex. reading time), we suggest injecting frontmatter via remark plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins';
+
+const COMPILED_CONTENT_ERROR =
+ 'MDX does not support compiledContent()! If you need to read the HTML contents to calculate values (ex. reading time), we suggest injecting frontmatter via rehype plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins';
+
function handleExtends<T>(config: WithExtends<T[] | undefined>, defaults: T[] = []): T[] {
if (Array.isArray(config)) return config;
@@ -127,6 +133,19 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
if (!moduleExports.includes('file')) {
code += `\nexport const file = ${JSON.stringify(fileId)};`;
}
+ if (!moduleExports.includes('rawContent')) {
+ code += `\nexport function rawContent() { throw new Error(${JSON.stringify(
+ RAW_CONTENT_ERROR
+ )}) };`;
+ }
+ if (!moduleExports.includes('compiledContent')) {
+ code += `\nexport function compiledContent() { throw new Error(${JSON.stringify(
+ COMPILED_CONTENT_ERROR
+ )}) };`;
+ }
+ if (!moduleExports.includes('Content')) {
+ code += `\nexport const Content = MDXContent;`;
+ }
if (command === 'dev') {
// TODO: decline HMR updates until we have a stable approach
diff --git a/packages/integrations/mdx/test/fixtures/mdx-component/src/pages/glob.astro b/packages/integrations/mdx/test/fixtures/mdx-component/src/pages/glob.astro
new file mode 100644
index 000000000..ae857fe27
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/mdx-component/src/pages/glob.astro
@@ -0,0 +1,11 @@
+---
+const components = await Astro.glob('../components/*.mdx');
+---
+
+<div data-default-export>
+ {components.map(Component => <Component.default />)}
+</div>
+
+<div data-content-export>
+ {components.map(({ Content }) => <Content />)}
+</div>
diff --git a/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/layouts/Base.astro b/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/layouts/Base.astro
index e4fa7560a..9a1c84c9d 100644
--- a/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/layouts/Base.astro
+++ b/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/layouts/Base.astro
@@ -1,7 +1,11 @@
---
const {
content = { title: "content didn't work" },
- frontmatter = { title: "frontmatter didn't work" },
+ frontmatter = {
+ title: "frontmatter didn't work",
+ file: "file didn't work",
+ url: "url didn't work",
+ },
headings = [],
} = Astro.props;
---
@@ -18,6 +22,8 @@ const {
<body>
<p data-content-title>{content.title}</p>
<p data-frontmatter-title>{frontmatter.title}</p>
+ <p data-frontmatter-file>{frontmatter.file}</p>
+ <p data-frontmatter-url>{frontmatter.url}</p>
<p data-layout-rendered>Layout rendered!</p>
<ul data-headings>
{headings.map(heading => <li>{heading.slug}</li>)}
diff --git a/packages/integrations/mdx/test/mdx-component.test.js b/packages/integrations/mdx/test/mdx-component.test.js
index 1a610be05..84210b342 100644
--- a/packages/integrations/mdx/test/mdx-component.test.js
+++ b/packages/integrations/mdx/test/mdx-component.test.js
@@ -19,7 +19,7 @@ describe('MDX Component', () => {
await fixture.build();
});
- it('works', async () => {
+ it('supports top-level imports', async () => {
const html = await fixture.readFile('/index.html');
const { document } = parseHTML(html);
@@ -29,6 +29,28 @@ describe('MDX Component', () => {
expect(h1.textContent).to.equal('Hello component!');
expect(foo.textContent).to.equal('bar');
});
+
+ it('supports glob imports - <Component.default />', async () => {
+ const html = await fixture.readFile('/glob/index.html');
+ const { document } = parseHTML(html);
+
+ const h1 = document.querySelector('[data-default-export] h1');
+ const foo = document.querySelector('[data-default-export] #foo');
+
+ expect(h1.textContent).to.equal('Hello component!');
+ expect(foo.textContent).to.equal('bar');
+ });
+
+ it('supports glob imports - <Content />', async () => {
+ const html = await fixture.readFile('/glob/index.html');
+ const { document } = parseHTML(html);
+
+ const h1 = document.querySelector('[data-content-export] h1');
+ const foo = document.querySelector('[data-content-export] #foo');
+
+ expect(h1.textContent).to.equal('Hello component!');
+ expect(foo.textContent).to.equal('bar');
+ });
});
describe('dev', () => {
@@ -42,7 +64,7 @@ describe('MDX Component', () => {
await devServer.stop();
});
- it('works', async () => {
+ it('supports top-level imports', async () => {
const res = await fixture.fetch('/');
expect(res.status).to.equal(200);
@@ -56,5 +78,35 @@ describe('MDX Component', () => {
expect(h1.textContent).to.equal('Hello component!');
expect(foo.textContent).to.equal('bar');
});
+
+ it('supports glob imports - <Component.default />', async () => {
+ const res = await fixture.fetch('/glob');
+
+ expect(res.status).to.equal(200);
+
+ const html = await res.text();
+ const { document } = parseHTML(html);
+
+ const h1 = document.querySelector('[data-default-export] h1');
+ const foo = document.querySelector('[data-default-export] #foo');
+
+ expect(h1.textContent).to.equal('Hello component!');
+ expect(foo.textContent).to.equal('bar');
+ });
+
+ it('supports glob imports - <Content />', async () => {
+ const res = await fixture.fetch('/glob');
+
+ expect(res.status).to.equal(200);
+
+ const html = await res.text();
+ const { document } = parseHTML(html);
+
+ const h1 = document.querySelector('[data-content-export] h1');
+ const foo = document.querySelector('[data-content-export] #foo');
+
+ expect(h1.textContent).to.equal('Hello component!');
+ expect(foo.textContent).to.equal('bar');
+ });
});
});
diff --git a/packages/integrations/mdx/test/mdx-frontmatter.test.js b/packages/integrations/mdx/test/mdx-frontmatter.test.js
index e69919bd5..9f0e9d8e6 100644
--- a/packages/integrations/mdx/test/mdx-frontmatter.test.js
+++ b/packages/integrations/mdx/test/mdx-frontmatter.test.js
@@ -56,4 +56,15 @@ describe('MDX frontmatter', () => {
expect(headingSlugs).to.contain('section-1');
expect(headingSlugs).to.contain('section-2');
});
+
+ it('passes "file" and "url" to layout via frontmatter', async () => {
+ const html = await fixture.readFile('/with-headings/index.html');
+ const { document } = parseHTML(html);
+
+ const frontmatterFile = document.querySelector('[data-frontmatter-file]')?.textContent;
+ const frontmatterUrl = document.querySelector('[data-frontmatter-url]')?.textContent;
+
+ expect(frontmatterFile?.endsWith('with-headings.mdx')).to.equal(true, '"file" prop does not end with correct path or is undefined');
+ expect(frontmatterUrl).to.equal('/with-headings');
+ });
});