Comments (12)
I think when filtering out draft content for the production build, it's best to do it as close to the source as possible. There might be multiple places where draft content shows up on your site and if you don't do the filtering until you've reached gatsby-node
's page creation, you would have to implement the filtering in all of these places individually. For blog posts that might be your blog's index page and/or landing page that displays a list of most recent posts. This leads to verbosity and, if you forget a place, might leak your draft content.
If the content is part of the site's repo, a solution that avoids these problems is to use gatsby-source-filesystem
's ignore
option. You could add a prefix such as draft-
to all files containing draft content and combine that with
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content`,
ignore: process.env.NODE_ENV === `production` && [`**/draft-*`]
}
}
Then, once the content is ready to be published, simply remove the file's draft-
prefix and build. An additional advantage to this approach is that it works with both files and folders. If you want to exclude multiple files, simply add the prefix to the parent directory. For example, you could have a permanent drafts
folder and move posts or any other type of content in and out of this folder as needed.
from gatsby.
I'm doing something similar to what @abrad45 recommended. Except I don't exclude the "draft posts" from my query, I filter them after that promise resolves based on my NODE_ENV.
I want to see all posts in my dev environment, but don't want to generate them when I build the static site for production. Here's my example, if you're curious:
exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators;
const blogPostTemplate = path.resolve(`src/templates/blog-post.js`);
return graphql(`{
allMarkdownRemark {
edges {
node {
html
id
frontmatter {
title
date(formatString: "MMMM DD YYYY")
path
tags
excerpt
published
}
}
}
}
}`)
.then(result => {
if (result.errors) {
return Promise.reject(result.errors);
}
const allPosts = result.data.allMarkdownRemark.edges;
const allowedPosts = allPosts.filter(post =>
(process.env.NODE_ENV === 'development'
|| post.node.frontmatter.published));
allowedPosts.forEach(({node}) => {
createPage({
path: node.frontmatter.path,
component: blogPostTemplate
});
});
});
};
from gatsby.
Frontmatter has published
:
Set to false if you donβt want a specific post to show up when the site is generated.
from gatsby.
gatsby currently doesn't have any predefined fields in frontmatter so you can add published
field but it's up to you to honor that field in your gatsby-node.js
.
For example in your createPages
function you can modify query that gets markdown nodes from data layer to allMarkdownRemark(filter:{frontmatter:{published:{ne:false}}})
(create pages from markdown that doesn't have published field set to false - so if you don't specify that field, page gets created) or allMarkdownRemark(filter:{frontmatter:{published:{eq:true}}})
(so you would need to specify it to true to create page)
from gatsby.
isn't this already implemented by using an underscore as the first character in the filename?
from gatsby.
Kinda. That's for template files which are still included but not outputted as html files. This issue is about not including a file at all in the production build. E.g. a draft blog post. Probably this would be implemented by excluding the file when globbing.
from gatsby.
Closing this. There's too many ways of doing this to handle it easily within Gatsby. Simple way not to have file built β move it somewhere else!
from gatsby.
Sorry to dredge up something from nearly two years ago, but I feel that supporting published: false
for draft posts is worthwhile. At worst, documentation is outdated:
From https://www.npmjs.com/package/gatsby-transformer-remark:
All frontmatter fields are converted into GraphQL fields.
That's not true, as adding in your own frontmatter fields does not work, nor does published
as outlined on https://jekyllrb.com/docs/frontmatter/
from gatsby.
@pieh sorry for the delay. Took me a few days to sit down and play with this a bit more. I have this snippet in my gatsby-node.js
and every post is returned, even ones with published: false
in the frontmatter. I'm wondering if possible frontmatter values are whitelisted or something?
exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators;
const blogPostTemplate = path.resolve('src/templates/blog.jsx');
return graphql(`
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
limit: 1000
filter: { frontmatter: { published: { ne: false } } }
) {
edges {
node {
html
frontmatter {
path
}
}
}
}
}
`).then(result => {
if (result.errors) {
return Promise.reject(result.errors);
}
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.frontmatter.path,
component: blogPostTemplate,
});
});
});
};
from gatsby.
@pieh Aha!
I learned something important about Gatsby tonight :)
The above code worked as you said it would. It prevented pages with published: false
in the frontmatter from being rendered. What it did not do is prevent them from appearing on /
in the post list, because that data comes from src/pages/index.jsx
. I kinda wish that Gatsby had one source of truth that different pages / contexts could draw from (a la redux
stores) but I am new to GraphQL, so maybe I'll much prefer this as I get more used to it.
In short, yes this works, and no frontmatter does not have a white list. And, in the case of my blog, I actually want to do the opposite of what I was doing: I'll be making detail pages for draft posts, but not linking to them on the index so I can see how they'll look before I publish them.
Thanks for the help. I appreciate it.
from gatsby.
I really think it would make more sense if it would be possible to exclude posts based on frontmatter from GraphQL data layer, should be standard Gatsby feature! ;)
from gatsby.
@janosh seems to have the most straightforward answer to this question. I like how I can see at a glance what posts are drafts and how it's agnostic of filetype, instead of having to dig around with GraphQL queries or frontmatter processing.
from gatsby.
Related Issues (20)
- `allMarkdownRemark` graphql query in `createPages` intermittently hangs when `excerpt` or `timeToRead` fields are included
- function build error: Error: Module build failed: UnhandledSchemeError HOT 2
- Gatsby 5 is dead? HOT 1
- webpack and other js resources not found when using a subfolder of a static s3 website to serve public files
- Gatsby static site generation not fully prerendering HTML with loadable imports
- Gatsby minimal TS starter generates code with deprecated React import
- gatsby-transformer-remark doesn't accept "engines" plugin option for graymatter
- matchPath seems to be broken since adapters
- The first Headless CMS starter link is broken
- Gatsby + Directus = Build not working HOT 1
- Validation error
- Unexpected missing while creating page
- Invoking imported function inside `createPages` results in error HOT 1
- Gatsby 4 Upgrade - SyntaxError: Invalid left-hand side in assignment
- command curl -X POST http://localhost:8000/__refresh doesn't delete the documents from the CMS
- Serverless function in Gatsby site throwing error and not returning data locally
- Using webpack-dev-middleware results with npm audit high vulnerability
- Add a short how-to article for removing the 8px margin in html body
- Error using TypeScript package using workspace in gatsby-node.ts : ReferenceError: Cannot access 'D' before initialization
- React Peer Dependency Issue with gatsby-plugin-mdx HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gatsby.