Guides

Filtering Posts

Each post defines a set of metadata using frontmatter format. There are a few properties that are generated by default by Nextein: category, page and date. You can override any property using the frontmatter section.

These properties are available through the post.data object. You can define your own properties like tags, author, etc.

Using Categories

The category property follows the directory structure by default. If you have a post located at posts/nodejs/start/hello-world.md then nodejs/start is assigned as its category.

The most common case is to filter posts by category. Nextein exposes a filter function to help: inCategory(category, options). This method uses the post.data to filter posts by a given category:

import { getPosts } from 'nextein/fetcher'
import Content from 'nextein/content'
import { inCategory } from 'nextein/filters'

export async function getStaticProps () {
  return { props: { posts: await getPosts() } }
}

export default function Index ({ posts }) {
  const blog = posts.filter(inCategory('blog'))

  return (
    <main>
    {
      blog.map(post => (        
        <article key={post.__id}>
          <h1>{post.data.title}</h1>
          <Content {...post} excerpt />
        </article>
      ))
    }
    </main>
  )
}

In this example we are listing only the posts with category: 'blog' and showing only the first paragraph by using the excerpt property in the <Content /> tag.

SubCategories

If you have sub categories such as blog, blog/react and blog/nodejs the example above will only list those posts with category: 'blog'. To include the posts in the sub categories you need to pass the includeSubCategories: true in the options object.


const blog = posts.filter(inCategory('blog', { includeSubCategories: true }))

Custom Filtering

In case you want to use your own filter, the posts property is an Array and can be filtered out by the usual means. For instance, if we want to also filter out our blog posts by author we could write a filter function like this:

const byAuthor = (author) => (post) => {
  return post.data.author === author
}

//...

const maxBlog = posts
  .filter(inCategory('blog', { includeSubCategories: true }))
  .filter(byAuthor('max'))

Using getPostFilterBy

You can use the getPostFilterBy to avoid to process all posts and filtering them in your render method.

Our previous example can be simplified by doing:

import { getPostsFilterBy } from 'nextein/fetcher'
import Content from 'nextein/content'
import { inCategory } from 'nextein/filters'

export async function getStaticProps () {
  return { props: { bllog: await getPostsFilterBy(inCategory('blog')) } }
}

export default function Index ({ blog }) {
  return (
    <main>
    {
      blog.map(post => (        
        <article key={post.__id}>
          <h1>{post.data.title}</h1>
          <Content {...post} excerpt />
        </article>
      ))
    }
    </main>
  )
}

This is the preferred way in case you have a large amount of posts and you display just a small set.

Note

Filtering posts using the getPostsFilterBy method will help performance since we are not adding unnecessary posts into the global cache, reducing the size of the final HTML file.