Draft Posts in Eleventy
Draft Eleventy posts are included on the front end in development mode only, not on the production site. When using version control software (VCS) the simplest way to make a post dev-only is to not track it— with Git, for example, do not commit the file. But with that approach you miss out on tracking changes to the draft, and you can’t distinguish drafts from published posts on the front end. Another option is a dedicated drafts’ Eleventy collection. But that approach can require reworking plugins to consume both the published posts’ collection and the drafts’ collection (for example when displaying all or related posts); and, with Eleventy’s path-based collections, publishing will require relocating the post file which can complicate looking at its VCS history. A good third option hinges on adding a new “draft” data field to posts.
We’ll need a way to distinguish development and production environments. The standard solution is to store an environment-specific variable in an .env file, and to use
dotenv to access the env variable in the site JS.
gitignore the path
.envfiles are often used to store sensitive information (read Algolia Search in VuePress Without Joining DocSearch for an example). Here, it will help us distinguish between “dev” and non-“dev” environments.
Create a file
.envin your project root, and define
I like to use an
.env.examplefile to keep a record of all expected environment variables. I leave out sensitive information; “true” isn’t sensitive, so it’s safe to leave in. Then, if you or someone else clones the project, they can
dotenvdependency. Instructions in the
dotenvdocs. In my case, that’s
In production, draft should not be written to the file system (the page should not exist) and they should be excluded from collections (keep them out of post archives, “related post” sections, and anything else that uses a
eleventyExcludeFromCollections: true in a post’s front matter will exclude it from collections. Setting
permalink: false will keep it from being written to the file system. So one way of marking a post as a “draft” is
But if you set
eleventyExcludeFromCollections: true or
permalink: false on any posts for a reason other than its being a draft, keeping track of true drafts will be tough.
The solution is to make that data dynamic. Then draft status and publication date can be used as factors in
draft: true in a post’s front matter will make it a draft, and it will not be part of production builds.
With a bunch of drafts in the hopper, “all posts” lists can be cluttered and significantly different in development from in production. Consider grouping drafts together. The Eleventy docs suggest creating a new
collection with a custom sort; I prefer a custom Eleventy filter.
draft data can be used to surface draft status on the front end: