Ensure file and url are always present in MDX for Astro.glob (#4076)
This commit is contained in:
parent
6fb95dbdd6
commit
6120a71e54
6 changed files with 100 additions and 5 deletions
5
.changeset/silent-files-promise.md
Normal file
5
.changeset/silent-files-promise.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@astrojs/mdx': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Ensure file and url are always present in MDX for Astro.glob
|
|
@ -96,10 +96,14 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
|
||||||
// or otherwise refactored to not require copy-paste handling logic.
|
// or otherwise refactored to not require copy-paste handling logic.
|
||||||
code += `\nimport "${'astro:scripts/page-ssr.js'}";`;
|
code += `\nimport "${'astro:scripts/page-ssr.js'}";`;
|
||||||
|
|
||||||
|
const { fileUrl, fileId } = getFileInfo(id, config);
|
||||||
if (!moduleExports.includes('url')) {
|
if (!moduleExports.includes('url')) {
|
||||||
const { fileUrl } = getFileInfo(id, config);
|
|
||||||
code += `\nexport const url = ${JSON.stringify(fileUrl)};`;
|
code += `\nexport const url = ${JSON.stringify(fileUrl)};`;
|
||||||
}
|
}
|
||||||
|
if (!moduleExports.includes('file')) {
|
||||||
|
code += `\nexport const file = ${JSON.stringify(fileId)};`;
|
||||||
|
}
|
||||||
|
|
||||||
if (command === 'dev') {
|
if (command === 'dev') {
|
||||||
// TODO: decline HMR updates until we have a stable approach
|
// TODO: decline HMR updates until we have a stable approach
|
||||||
code += `\nif (import.meta.hot) {
|
code += `\nif (import.meta.hot) {
|
||||||
|
|
|
@ -4,16 +4,34 @@ function appendForwardSlash(path: string) {
|
||||||
return path.endsWith('/') ? path : path + '/';
|
return path.endsWith('/') ? path : path + '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface FileInfo {
|
||||||
|
fileId: string;
|
||||||
|
fileUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
/** @see 'vite-plugin-utils' for source */
|
/** @see 'vite-plugin-utils' for source */
|
||||||
export function getFileInfo(id: string, config: AstroConfig) {
|
export function getFileInfo(id: string, config: AstroConfig): FileInfo {
|
||||||
const sitePathname = appendForwardSlash(
|
const sitePathname = appendForwardSlash(
|
||||||
config.site ? new URL(config.base, config.site).pathname : config.base
|
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];
|
const fileId = id.split('?')[0];
|
||||||
let fileUrl = fileId.includes('/pages/')
|
let fileUrl: string;
|
||||||
? fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.mdx$/, '')
|
const isPage = fileId.includes('/pages/');
|
||||||
: undefined;
|
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') {
|
if (fileUrl && config.trailingSlash === 'always') {
|
||||||
fileUrl = appendForwardSlash(fileUrl);
|
fileUrl = appendForwardSlash(fileUrl);
|
||||||
}
|
}
|
||||||
|
|
5
packages/integrations/mdx/test/fixtures/mdx-get-static-paths/src/content/1.mdx
vendored
Normal file
5
packages/integrations/mdx/test/fixtures/mdx-get-static-paths/src/content/1.mdx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
one: hello
|
||||||
|
slug: one
|
||||||
|
---
|
||||||
|
First mdx file
|
34
packages/integrations/mdx/test/fixtures/mdx-get-static-paths/src/pages/[slug].astro
vendored
Normal file
34
packages/integrations/mdx/test/fixtures/mdx-get-static-paths/src/pages/[slug].astro
vendored
Normal file
|
@ -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
packages/integrations/mdx/test/mdx-get-static-paths.test.js
Normal file
29
packages/integrations/mdx/test/mdx-get-static-paths.test.js
Normal file
|
@ -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');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue