next.jsalgoliasanitygroq

sanity-algolia get error when using pt::text


I'm trying to integrate algolia search with sanity CMS using the sanity-algolia library (ref https://www.sanity.io/plugins/sanity-algolia)

But when i try to get the plain text from Portable Text rich text content using the pt::text function. i get expected '}' following object body , and i dont really know where im missing a bracket.

(another note: since im hosting sanity by using sanity start, I am using nextjs (my frontend) to run the function instead using the /api routes in nextJS) So sanity has a webhook to this route.

details about the error:

  details: {
    description: "expected '}' following object body",
    end: 174,
    query: '* [(_id in $created || _id in $updated) && _type in $types] {\n' +
      '  _id,\n' +
      '  _type,\n' +
      '  _rev,\n' +
      '  _type == "post" => {\n' +
      '        title,\n' +
      '        "path": slug.current,\n' +
      '        "body": pt::text(body)\n' +
      '      }\n' +
      '}',
    start: 107,
    type: 'queryParseError'
  }

this is the serverless function im running:

export default async function handler(req, res) {
  if (req.headers["content-type"] !== "application/json") {
    res.status(400);
    res.json({ message: "Bad request" });
    return;
  }

  const algoliaIndex = algolia.initIndex("dev_kim_miles");

  const sanityAlgolia = indexer(
    {
      post: {
        index: algoliaIndex,
        projection: `{
        title,
        "path": slug.current,
        "body": pt::text(body)
      }`,
      },
    },
    (document) => {
      console.log(document);
      return document;
    },
    (document) => {
      if (document.hasOwnProperty("isHidden")) {
        return !document.isHidden;
      }
      return true;
    }
  );
  return sanityAlgolia
    .webhookSync(sanityClient, req.body)
    .then(() => res.status(200).send("ok"));
}

and my post schema from sanity:

export default {
  name: 'post',
  title: 'Post',
  type: 'document',
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: 'string',
    },
    {
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      options: {
        source: 'title',
        maxLength: 96,
      },
    },
    {
      name: 'author',
      title: 'Author',
      type: 'reference',
      to: {type: 'author'},
    },
    {
      name: 'mainImage',
      title: 'Main image',
      type: 'image',
      options: {
        hotspot: true,
      },
    },
    {
      name: 'categories',
      title: 'Categories',
      type: 'array',
      of: [{type: 'reference', to: {type: 'category'}}],
    },
    {
      name: 'publishedAt',
      title: 'Published at',
      type: 'datetime',
    },
    {
      name: 'body',
      title: 'Body',
      type: 'blockContent',
    },
    {
      name: 'extra',
      title: 'extra',
      type: 'blockContent',
    },
  ],

  preview: {
    select: {
      title: 'title',
      author: 'author.name',
      media: 'mainImage',
    },
    prepare(selection) {
      const {author} = selection
      return Object.assign({}, selection, {
        subtitle: author && `by ${author}`,
      })
    },
  },
}

Solution

  • sanity api v1 doesnt work with functions, I was using

    const sanityClient = client({
      dataset: "production",
      useCdn: true,
      projectId: "project_id",
    });
    

    which defaults to v1, but in order to use function i added a apiVersion parameter, which made it use later api version:

    const sanityClient = client({
      dataset: "production",
      useCdn: true,
      projectId: "9dz8b3g1",
      apiVersion: "2021-03-25",
    });