How to filter by slug in notion api

1k Views Asked by At

I am trying to get a page from a database in notion through the slug, but when filtering it gives me an error the error is:

@notionhq/client warn: request fail {
  code: 'validation_error',
  message: 'body failed validation. Fix one:\n' +
    'body.filter.formula.string should be defined, instead was `undefined`.\n' +
    'body.filter.formula.checkbox should be defined, instead was `undefined`.\n' +
    'body.filter.formula.number should be defined, instead was `undefined`.\n' +
    'body.filter.formula.date should be defined, instead was `undefined`.'
}

i use next.js

my controller is notion.js:


export async function getSingleBlogPost(slug) {
  const database = process.env.NOTION_BLOG_DATABASE_ID ?? '';

  // list of blog posts
  const response = await client.databases.query({
    database_id: database,
    filter: {
      property: 'Slug',
      formula: {
        text: {
          equals: slug, // slug
        },
      },
      // add option for tags in the future
    },
    sorts: [
      {
        property: 'Updated',
        direction: 'descending',
      },
    ],
  });

  if (!response.results[0]) {
    throw 'No results available';
  }

  const page = response.results[0];
  const mdBlocks = await n2m.pageToMarkdown(page.id);
  const post = await pageToPostTransformer(page);
  const markdown = n2m.toMarkdownString(mdBlocks);

  return {
    post,
    markdown,
  };
}

for more code of my file view: https://pastebin.com/RapTGN38

in my [slug].jsx:

import ReactMarkdown from "react-markdown";
import Head from "next/head";

import {getSingleBlogPost, getPublishedBlogPosts} from '../../lib/notion.js'

const Post = ({markdown, post}) => {
    return (
        <>
            <Head>
                <title>{post.title}</title>
                <meta name={"description"} title={"description"} content={post.description}/>
                <meta name={"og:title"} title={"og:title"} content={post.title}/>
                <meta name={"og:description"} title={"og:description"} content={post.description}/>
                <meta name={"og:image"} title={"og:image"} content={post.cover}/>
            </Head>

            <div className="min-h-screen">
                <main className="max-w-5xl mx-auto relative">
                    <div className="flex items-center justify-center">
                        <article className="prose">
                            <ReactMarkdown>{markdown}</ReactMarkdown>
                        </article>
                    </div>
                </main>
            </div>

        </>
    )
}

export const getStaticProps = async (context) => {

    // @ts-ignore
    const p = await getSingleBlogPost(context.params?.slug)

    if (!p) {
        throw ''
    }

    return {
        props: {
            markdown: p.markdown,
            post: p.post
        },
    }
}

export async function getStaticPaths() {

    const posts = await getPublishedBlogPosts()

    // Because we are generating static paths, you will have to redeploy your site whenever
    // you make a change in Notion.
    const paths = posts.map(post => {
        return `/post/${post.slug}`
    })

    return {
        paths,
        fallback: false,
    }
}

export default Post;

i want to make my personal blog, when i open a link of a post, I receive this error

1

There are 1 best solutions below

0
On BEST ANSWER

Liendo, I hope I'm not too late for your problem !

If you read carrefully the notion API error, it give you the answer :

Fix one:\n' +
'body.filter.formula.string should be defined, instead was `undefined`.\n' +
'body.filter.formula.checkbox should be defined, instead was `undefined`.\n' +
'body.filter.formula.number should be defined, instead was `undefined`.\n' +
'body.filter.formula.date should be defined, instead was `undefined`.'

So it's mean in your filter, in the formula object, you need to replace text with one of the attributes above (string or checkbox or number or date) because one of them need to be defined. I guess your slug is a string type, so your filter will be :

filter: {
      property: 'Slug',
      formula: {
        string: {
          equals: slug,
        },
      },
    },

It should worked !