Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for other markdown file extensions #5164

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/spicy-cameras-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'astro': patch
MoustaphaDev marked this conversation as resolved.
Show resolved Hide resolved
'@astrojs/rss': patch
'@astrojs/mdx': patch
---

Support `.markdown` file extension for markdown files
MoustaphaDev marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions packages/astro-rss/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type RSSOptions = {
/**
* List of RSS feed items to render. Accepts either:
* a) list of RSSFeedItems
* b) import.meta.glob result. You can only glob ".md" files within src/pages/ when using this method!
* b) import.meta.glob result. You can only glob ".md" or ".markdown" files within src/pages/ when using this method!
*/
items: RSSFeedItem[] | GlobResult;
/** Specify arbitrary metadata on opening <xml> tag */
Expand Down Expand Up @@ -58,7 +58,7 @@ function mapGlobResult(items: GlobResult): Promise<RSSFeedItem[]> {
const { url, frontmatter } = await getInfo();
if (url === undefined || url === null) {
throw new Error(
`[RSS] When passing an import.meta.glob result directly, you can only glob ".md" files within /pages! Consider mapping the result to an array of RSSFeedItems. See the RSS docs for usage examples: https://docs.astro.build/en/guides/rss/#2-list-of-rss-feed-objects`
`[RSS] When passing an import.meta.glob result directly, you can only glob ".md" or ".markdown" files within /pages! Consider mapping the result to an array of RSSFeedItems. See the RSS docs for usage examples: https://docs.astro.build/en/guides/rss/#2-list-of-rss-feed-objects`
);
}
if (!Boolean(frontmatter.title) || !Boolean(frontmatter.pubDate)) {
Expand Down
16 changes: 16 additions & 0 deletions packages/astro/client-base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ declare module '*.md' {
const load: MD['default'];
export default load;
}
declare module '*.markdown' {
type MD = import('./dist/@types/astro').MarkdownInstance<Record<string, any>>;

export const frontmatter: MD['frontmatter'];
export const file: MD['file'];
export const url: MD['url'];
export const getHeadings: MD['getHeadings'];
/** @deprecated Renamed to `getHeadings()` */
export const getHeaders: () => void;
export const Content: MD['Content'];
export const rawContent: MD['rawContent'];
export const compiledContent: MD['compiledContent'];

const load: MD['default'];
export default load;
}

declare module '*.mdx' {
type MDX = import('./dist/@types/astro').MDXInstance<Record<string, any>>;
Expand Down
6 changes: 4 additions & 2 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ export interface AstroGlobalPartial {
* [Astro reference](https://docs.astro.build/en/reference/api-reference/#astroglob)
*/
glob(globStr: `${any}.astro`): Promise<AstroInstance[]>;
glob<T extends Record<string, any>>(globStr: `${any}.md`): Promise<MarkdownInstance<T>[]>;
glob<T extends Record<string, any>>(
globStr: `${any}.md` | `${any}.markdown`
): Promise<MarkdownInstance<T>[]>;
glob<T extends Record<string, any>>(globStr: `${any}.mdx`): Promise<MDXInstance<T>[]>;
glob<T extends Record<string, any>>(globStr: string): Promise<T[]>;
/**
Expand Down Expand Up @@ -868,7 +870,7 @@ export interface AstroUserConfig {
* @default `false`
* @version 1.0.0-rc.1
* @description
* Enable Astro's pre-v1.0 support for components and JSX expressions in `.md` Markdown files.
* Enable Astro's pre-v1.0 support for components and JSX expressions in `.md` and `.markdown` Markdown files.
* In Astro `1.0.0-rc`, this original behavior was removed as the default, in favor of our new [MDX integration](/en/guides/integrations-guide/mdx/).
*
* To enable this behavior, set `legacy.astroFlavoredMarkdown` to `true` in your [`astro.config.mjs` configuration file](/en/guides/configuring-astro/#the-astro-config-file).
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function moduleIsTopLevelPage(info: ModuleInfo): boolean {
}

// This function walks the dependency graph, going up until it finds a page component.
// This could be a .astro page or a .md page.
// This could be a .astro page, a .markdown or a .md page.
export function* getTopLevelPages(
id: string,
ctx: { getModuleInfo: GetModuleInfo }
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function createSettings(config: AstroConfig, cwd?: string): AstroSettings

adapter: undefined,
injectedRoutes: [],
pageExtensions: ['.astro', '.md', '.html'],
pageExtensions: ['.astro', '.md', '.html', '.markdown'],
renderers: [jsxRenderer],
scripts: [],
watchFiles: tsconfig?.exists ? [tsconfig.path, ...tsconfig.extendedPaths] : [],
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/render/dev/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { STYLE_EXTENSIONS } from '../util.js';
* List of file extensions signalling we can (and should) SSR ahead-of-time
* See usage below
*/
const fileExtensionsToSSR = new Set(['.astro', '.md']);
const fileExtensionsToSSR = new Set(['.astro', '.md', '.markdown']);

const STRIP_QUERY_PARAMS_REGEX = /\?.*$/;

Expand Down
7 changes: 6 additions & 1 deletion packages/astro/src/core/routing/manifest/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,12 @@ export function createRouteManifest(
): ManifestData {
const components: string[] = [];
const routes: RouteData[] = [];
const validPageExtensions: Set<string> = new Set(['.astro', '.md', ...settings.pageExtensions]);
const validPageExtensions: Set<string> = new Set([
'.astro',
'.md',
'.markdown',
...settings.pageExtensions,
]);
const validEndpointExtensions: Set<string> = new Set(['.js', '.ts']);

function walk(dir: string, parentSegments: RoutePart[][], parentParams: string[]) {
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/vite-plugin-astro-postprocess/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export default function astro(_opts: AstroPluginOptions): Plugin {
return {
name: 'astro:postprocess',
async transform(code, id) {
// Currently only supported in ".astro" & ".md" files
if (!id.endsWith('.astro') && !id.endsWith('.md')) {
// Currently only supported in ".astro", ".md" & ".markdown" files
if (!id.endsWith('.astro') && !id.endsWith('.md') && !id.endsWith('.markdown')) {
return null;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/vite-plugin-jsx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default function jsx({ settings, logging }: AstroPluginJSXOptions): Plugi

const { mode } = viteConfig;
// Shortcut: only use Astro renderer for MD and MDX files
if (id.includes('.mdx') || id.includes('.md')) {
if (id.includes('.mdx') || id.includes('.md') || id.includes('.markdown')) {
const { code: jsxCode } = await esbuild.transform(code, {
loader: getEsbuildLoader(path.extname(id)) as esbuild.Loader,
jsx: 'preserve',
Expand Down
16 changes: 11 additions & 5 deletions packages/astro/src/vite-plugin-markdown-legacy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,21 @@ export default function markdown({ settings }: AstroPluginOptions): Plugin {
styleTransformer.viteDevServer = server;
},
async resolveId(id, importer, options) {
// Resolve any .md files with the `?content` cache buster. This should only come from
// Resolve any .md or .markdown files with the `?content` cache buster. This should only come from
// an already-resolved JS module wrapper. Needed to prevent infinite loops in Vite.
// Unclear if this is expected or if cache busting is just working around a Vite bug.
if (id.endsWith(`.md${MARKDOWN_CONTENT_FLAG}`)) {
if (
id.endsWith(`.md${MARKDOWN_CONTENT_FLAG}`) ||
id.endsWith(`.markdown${MARKDOWN_CONTENT_FLAG}`)
) {
const resolvedId = await this.resolve(id, importer, { skipSelf: true, ...options });
return resolvedId?.id.replace(MARKDOWN_CONTENT_FLAG, '');
}
// If the markdown file is imported from another file via ESM, resolve a JS representation
// that defers the markdown -> HTML rendering until it is needed. This is especially useful
// when fetching and then filtering many markdown files, like with import.meta.glob() or Astro.glob().
// Otherwise, resolve directly to the actual component.
if (id.endsWith('.md') && !isRootImport(importer)) {
if ((id.endsWith('.md') || id.endsWith('.markdown')) && !isRootImport(importer)) {
const resolvedId = await this.resolve(id, importer, { skipSelf: true, ...options });
if (resolvedId) {
return resolvedId.id + MARKDOWN_IMPORT_FLAG;
Expand All @@ -103,7 +106,10 @@ export default function markdown({ settings }: AstroPluginOptions): Plugin {
// A markdown file has been imported via ESM!
// Return the file's JS representation, including all Markdown
// frontmatter and a deferred `import() of the compiled markdown content.
if (id.endsWith(`.md${MARKDOWN_IMPORT_FLAG}`)) {
if (
id.endsWith(`.md${MARKDOWN_IMPORT_FLAG}`) ||
id.endsWith(`.markdown${MARKDOWN_IMPORT_FLAG}`)
) {
const { fileId, fileUrl } = getFileInfo(id, config);

const source = await fs.promises.readFile(fileId, 'utf8');
Expand Down Expand Up @@ -143,7 +149,7 @@ export default function markdown({ settings }: AstroPluginOptions): Plugin {
// A markdown file is being rendered! This markdown file was either imported
// directly as a page in Vite, or it was a deferred render from a JS module.
// This returns the compiled markdown -> astro component that renders to HTML.
if (id.endsWith('.md')) {
if (id.endsWith('.md') || id.endsWith('.markdown')) {
const filename = normalizeFilename(id);
const source = await fs.promises.readFile(filename, 'utf8');
const renderOpts = config.markdown;
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/vite-plugin-markdown/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default function markdown({ settings, logging }: AstroPluginOptions): Plu
// passing to the transform hook. This lets us get the truly raw value
// to escape "import.meta.env" ourselves.
async load(id) {
if (id.endsWith('.md')) {
if (id.endsWith('.md') || id.endsWith('.markdown')) {
const { fileId, fileUrl } = getFileInfo(id, settings.config);
const rawFile = await fs.promises.readFile(fileId, 'utf-8');
const raw = safeMatter(rawFile, id);
Expand All @@ -63,7 +63,7 @@ export default function markdown({ settings, logging }: AstroPluginOptions): Plu
warn(
logging,
'markdown',
`[${id}] Astro now supports MDX! Support for components in ".md" files using the "setup" frontmatter is no longer enabled by default. Migrate this file to MDX or add the "legacy.astroFlavoredMarkdown" config flag to re-enable support.`
`[${id}] Astro now supports MDX! Support for components in ".md" or ".markdown" files using the "setup" frontmatter is no longer enabled by default. Migrate this file to MDX or add the "legacy.astroFlavoredMarkdown" config flag to re-enable support.`
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Page with markdown extension

Hope this loads fine 🤞
7 changes: 7 additions & 0 deletions packages/astro/test/markdown.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ describe('Markdown tests', () => {
await fixture.build();
});

it('Can load a `.markdown` file', async () => {
const html = await fixture.readFile('/page-with-markdown-extension/index.html');
const $ = cheerio.load(html);
expect($('h1').html()).to.equal('Page with markdown extension');
expect($('p').html()).to.equal('Hope this loads fine 🤞');
});
MoustaphaDev marked this conversation as resolved.
Show resolved Hide resolved

it('Can load a simple markdown page with Astro', async () => {
const html = await fixture.readFile('/post/index.html');
const $ = cheerio.load(html);
Expand Down
2 changes: 1 addition & 1 deletion packages/integrations/mdx/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
rehypePlugins: getRehypePlugins(mdxOptions, config),
jsx: true,
jsxImportSource: 'astro',
// Note: disable `.md` support
// Note: disable `.md` and `.markdown` support
format: 'mdx',
mdExtensions: [],
};
Expand Down