Skip to content

Commit

Permalink
Ensure file and url are always present in MDX for Astro.glob (#4076)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewp authored Jul 28, 2022
1 parent 6fb95db commit 6120a71
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-files-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/mdx': patch
---

Ensure file and url are always present in MDX for Astro.glob
6 changes: 5 additions & 1 deletion packages/integrations/mdx/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,14 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
// or otherwise refactored to not require copy-paste handling logic.
code += `\nimport "${'astro:scripts/page-ssr.js'}";`;

const { fileUrl, fileId } = getFileInfo(id, config);
if (!moduleExports.includes('url')) {
const { fileUrl } = getFileInfo(id, config);
code += `\nexport const url = ${JSON.stringify(fileUrl)};`;
}
if (!moduleExports.includes('file')) {
code += `\nexport const file = ${JSON.stringify(fileId)};`;
}

if (command === 'dev') {
// TODO: decline HMR updates until we have a stable approach
code += `\nif (import.meta.hot) {
Expand Down
26 changes: 22 additions & 4 deletions packages/integrations/mdx/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,34 @@ function appendForwardSlash(path: string) {
return path.endsWith('/') ? path : path + '/';
}

interface FileInfo {
fileId: string;
fileUrl: string;
}

/** @see 'vite-plugin-utils' for source */
export function getFileInfo(id: string, config: AstroConfig) {
export function getFileInfo(id: string, config: AstroConfig): FileInfo {
const sitePathname = appendForwardSlash(
config.site ? new URL(config.base, config.site).pathname : config.base
);

// Try to grab the file's actual URL
let url: URL | undefined = undefined;
try {
url = new URL(`file://${id}`);
} catch {}

const fileId = id.split('?')[0];
let fileUrl = fileId.includes('/pages/')
? fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.mdx$/, '')
: undefined;
let fileUrl: string;
const isPage = fileId.includes('/pages/');
if(isPage) {
fileUrl = fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.mdx$/, '');
} else if(url && url.pathname.startsWith(config.root.pathname)) {
fileUrl = url.pathname.slice(config.root.pathname.length);
} else {
fileUrl = fileId;
}

if (fileUrl && config.trailingSlash === 'always') {
fileUrl = appendForwardSlash(fileUrl);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
one: hello
slug: one
---
First mdx file
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
export const getStaticPaths = async () => {
const content = await Astro.glob('../content/*.mdx');
return content
.filter((page) => !page.frontmatter.draft) // skip drafts
.map(({ default: MdxContent, frontmatter, url, file }) => {
return {
params: { slug: frontmatter.slug || "index" },
props: {
MdxContent,
file,
frontmatter,
url
}
}
})
}
const { MdxContent, frontmatter, url, file } = Astro.props;
---

<html>
<head>
<title>Page</title>
</head>
<body>
<MdxContent />

<div id="one">{frontmatter.one}</div>
<div id="url">{url}</div>
<div id="file">{file}</div>
</body>
</html>
29 changes: 29 additions & 0 deletions packages/integrations/mdx/test/mdx-get-static-paths.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import mdx from '@astrojs/mdx';

import { expect } from 'chai';
import { loadFixture } from '../../../astro/test/test-utils.js';
import * as cheerio from 'cheerio';

const FIXTURE_ROOT = new URL('./fixtures/mdx-get-static-paths', import.meta.url);

describe('getStaticPaths', () => {
/** @type {import('astro/test/test-utils').Fixture} */
let fixture;
before(async () => {
fixture = await loadFixture({
root: FIXTURE_ROOT,
integrations: [mdx()],
});
await fixture.build();
});

it('Provides file and url', async () => {
const html = await fixture.readFile('/one/index.html');

const $ = cheerio.load(html);
expect($('p').text()).to.equal('First mdx file');
expect($('#one').text()).to.equal('hello', 'Frontmatter included');
expect($('#url').text()).to.equal('/src/content/1.mdx', 'url is included');
expect($('#file').text()).to.contain('fixtures/mdx-get-static-paths/src/content/1.mdx', 'file is included');
});
});

0 comments on commit 6120a71

Please sign in to comment.