diff --git a/.changeset/ten-cougars-knock.md b/.changeset/ten-cougars-knock.md
new file mode 100644
index 000000000..613616304
--- /dev/null
+++ b/.changeset/ten-cougars-knock.md
@@ -0,0 +1,15 @@
+---
+'astro': patch
+---
+
+Support markdown draft pages.
+Markdown draft pages are markdown pages which have `draft` set in their frontmatter. By default, these will not be built by Astro while running `astro build`. To disable this behavior, you need to set `buildOptions.drafts` to `true` or pass the `--drafts` flag while running `astro build`. An exaple of a markdown draft page is:
+```markdown
+---
+# src/pages/blog-post.md
+title: My Blog Post
+draft: true
+---
+
+This is my blog post which is currently incomplete.
+```
diff --git a/docs/src/pages/en/guides/markdown-content.md b/docs/src/pages/en/guides/markdown-content.md
index da4e38985..85d9b9ed8 100644
--- a/docs/src/pages/en/guides/markdown-content.md
+++ b/docs/src/pages/en/guides/markdown-content.md
@@ -98,6 +98,7 @@ Markdown pages have a special frontmatter property for `layout`. This defines th
# src/pages/index.md
layout: ../../layouts/BaseLayout.astro
title: My cool page
+draft: false
---
# Hello World!
@@ -128,6 +129,7 @@ For Markdown files, the `content` prop also has an `astro` property which holds
"date": "Tuesday, July 27 2021",
"author": "Matthew Phillips",
"description": "Astro 0.18 is our biggest release since Astro launch.",
+ "draft": false,
**/
"astro": {
"headers": [
@@ -159,6 +161,34 @@ Using images or videos follows Astro's normal import rules:
- Example: Image is located at `/public/assets/img/astonaut.png` → Markdown: `![Astronaut](assets/img/astronaut.png)`
- Or use `import` as explained on the [imports page](/en/guides/imports#other-assets) (when using Astro's Markdown Component)
+### Markdown draft pages
+
+Markdown pages which have the property `draft` set in their frontmatter are referred to as "draft pages". By default, Astro excludes these pages from the build when building the static version of your page (i.e `astro build`), which means that you can exclude draft/incomplete pages from the production build by setting `draft` to `true`. To enable building of draft pages, you can set `buildOptions.drafts` to `true` in the configuration file, or pass the `--drafts` flag when running `astro build`. Markdown pages which do not have the `draft` property set are not affected. An example of a markdown draft page can be:
+
+```markdown
+---
+# src/pages/blog-post.md
+title: My Blog Post
+draft: true
+---
+
+This is my blog post which is currently incomplete.
+```
+
+An example of a markdown post which is not a draft:
+
+```markdown
+---
+# src/pages/blog-post.md
+title: My Blog Post
+draft: false
+---
+
+This is my blog post...
+```
+
+> This feature only applies to local markdown pages, not the `` component, or remote markdown.
+
## Astro's Markdown Component
Astro has a dedicated component used to let you render your markdown as HTML components. This is a special component that is only exposed to `.astro` files. To use the `` component, within your frontmatter block use the following import statement:
diff --git a/docs/src/pages/en/reference/configuration-reference.md b/docs/src/pages/en/reference/configuration-reference.md
index 7d6cb37e9..82c535a65 100644
--- a/docs/src/pages/en/reference/configuration-reference.md
+++ b/docs/src/pages/en/reference/configuration-reference.md
@@ -61,7 +61,7 @@ The `renderers` option defines the framework renderers to be used by Astro.
#### buildOptions
-The `buildOptions` option configures how a site is built, including its base URL (`buildOptions.site`), whether it includes a sitemap (`buildOptions.sitemap`), and whether its pages should be files (`path.html`) or directories (`path/index.html`) (`buildOptions.pageUrlFormat`).
+The `buildOptions` option configures how a site is built, including its base URL (`buildOptions.site`), whether it includes a sitemap (`buildOptions.sitemap`), whether markdown draft pages should be included in the build (`buildOptions.drafts`), and whether its pages should be files (`path.html`) or directories (`path/index.html`) (`buildOptions.pageUrlFormat`).
#### devOptions
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 4185b25b8..a96bb10e9 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -108,6 +108,13 @@ export interface AstroUserConfig {
* Default: 'directory'
*/
pageUrlFormat?: 'file' | 'directory';
+ /**
+ * Control if markdown draft pages should be included in the build.
+ * `true`: Include draft pages
+ * `false`: Exclude draft pages
+ * Default: false
+ */
+ drafts?: boolean;
};
/** Options for the development server run with `astro dev`. */
devOptions?: {
diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts
index 60fe945a2..0031a08ae 100644
--- a/packages/astro/src/cli/index.ts
+++ b/packages/astro/src/cli/index.ts
@@ -26,6 +26,7 @@ interface CLIState {
port?: number;
config?: string;
experimentalStaticBuild?: boolean;
+ drafts?: boolean;
};
}
@@ -39,6 +40,7 @@ function resolveArgs(flags: Arguments): CLIState {
config: typeof flags.config === 'string' ? flags.config : undefined,
hostname: typeof flags.hostname === 'string' ? flags.hostname : undefined,
experimentalStaticBuild: typeof flags.experimentalStaticBuild === 'boolean' ? flags.experimentalStaticBuild : false,
+ drafts: typeof flags.drafts === 'boolean' ? flags.drafts : false,
};
if (flags.version) {
@@ -72,14 +74,15 @@ function printHelp() {
astro check Check your project for errors.
${colors.bold('Flags:')}
- --config Specify the path to the Astro config file.
- --project-root Specify the path to the project root folder.
- --no-sitemap Disable sitemap generation (build only).
- --experimental-static-build A more performant build that expects assets to be define statically.
- --verbose Enable verbose logging
- --silent Disable logging
- --version Show the version number and exit.
- --help Show this help message.
+ --config Specify the path to the Astro config file.
+ --project-root Specify the path to the project root folder.
+ --no-sitemap Disable sitemap generation (build only).
+ --experimental-static-build A more performant build that expects assets to be define statically.
+ --drafts Include markdown draft pages in the build.
+ --verbose Enable verbose logging
+ --silent Disable logging
+ --version Show the version number and exit.
+ --help Show this help message.
`);
}
@@ -99,6 +102,7 @@ function mergeCLIFlags(astroConfig: AstroConfig, flags: CLIState['options']) {
if (typeof flags.port === 'number') astroConfig.devOptions.port = flags.port;
if (typeof flags.hostname === 'string') astroConfig.devOptions.hostname = flags.hostname;
if (typeof flags.experimentalStaticBuild === 'boolean') astroConfig.buildOptions.experimentalStaticBuild = flags.experimentalStaticBuild;
+ if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
}
/** The primary CLI action */
diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts
index 3c08f4f61..f6b379942 100644
--- a/packages/astro/src/core/build/index.ts
+++ b/packages/astro/src/core/build/index.ts
@@ -85,6 +85,19 @@ class AstroBuilder {
routeCache: this.routeCache,
viteServer: this.viteServer,
});
+
+ // Filter pages by using conditions based on their frontmatter.
+ Object.entries(allPages).forEach(([page, data]) => {
+ if ('frontmatter' in data.preload[1]) {
+ // TODO: add better type inference to data.preload[1]
+ const frontmatter = (data.preload[1] as any).frontmatter;
+ if (Boolean(frontmatter.draft) && !this.config.buildOptions.drafts) {
+ debug(logging, 'build', timerMessage(`Skipping draft page ${page}`, timer.loadStart));
+ delete allPages[page];
+ }
+ }
+ });
+
debug(logging, 'build', timerMessage('All pages loaded', timer.loadStart));
// The names of each pages
diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts
index 1f8827023..6d5fd9a72 100644
--- a/packages/astro/src/core/config.ts
+++ b/packages/astro/src/core/config.ts
@@ -59,6 +59,7 @@ export const AstroConfigSchema = z.object({
.optional()
.default('directory'),
experimentalStaticBuild: z.boolean().optional().default(false),
+ drafts: z.boolean().optional().default(false),
})
.optional()
.default({}),
diff --git a/packages/astro/test/astro-markdown-drafts.test.js b/packages/astro/test/astro-markdown-drafts.test.js
new file mode 100644
index 000000000..beee3fd7f
--- /dev/null
+++ b/packages/astro/test/astro-markdown-drafts.test.js
@@ -0,0 +1,47 @@
+import { expect } from 'chai';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('Astro Markdown with draft posts disabled', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ projectRoot: './fixtures/astro-markdown-drafts/',
+ buildOptions: {
+ // drafts is false by default but added here for clarity
+ drafts: false,
+ sitemap: false,
+ },
+ });
+ await fixture.build();
+ });
+ it('Does not render the draft post', async () => {
+ try {
+ await fixture.readFile('/wip/index.html');
+ } catch (err) {
+ expect(err.code).to.equal('ENOENT');
+ }
+ });
+});
+
+describe('Astro Markdown with draft posts enabled', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ projectRoot: './fixtures/astro-markdown-drafts/',
+ buildOptions: {
+ drafts: true,
+ sitemap: false,
+ },
+ });
+ await fixture.build();
+ });
+ it('Renders the draft post', async () => {
+ const html = await fixture.readFile('/wip/index.html');
+ const $ = cheerio.load(html);
+ expect($('h1').length).to.be.ok;
+ expect($('h1').text()).to.equal('WIP');
+ });
+});
diff --git a/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/index.md b/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/index.md
new file mode 100644
index 000000000..0e06444da
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/index.md
@@ -0,0 +1,7 @@
+---
+foo: bar
+---
+
+# Hello world
+
+This should be visible.
\ No newline at end of file
diff --git a/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/wip.md b/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/wip.md
new file mode 100644
index 000000000..27b829614
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-markdown-drafts/src/pages/wip.md
@@ -0,0 +1,8 @@
+---
+foo: bar
+draft: true
+---
+
+# WIP
+
+This is a draft. Don't build me!
\ No newline at end of file