Error querying blog post by slug in Next.js project

6 replies
Last updated: Jun 27, 2023
Hello folks, I’m querying blog posts data from sanity in my nextjs project, I was successful at that, but I’m having error trying to query a blog post by slug. I will appreciate a second eye to look at what I might be doing wrong. Thanks
 error node_modules/@sanity/client/dist/index.cjs (90:12) @ onResponse
- error Error: unable to parse entire expression
    at Object.onceWrapper (node:events:641:28)
    at DestroyableTransform.emit (node:events:539:35)
This is how I’m querying it


export const getSinglePost = async (
  slug: string
): Promise<PostData["data"]> => {
  const client = createClient(clientConfig);

  return await client.fetch(
    groq`
  *[_type == "post" && slug.current == ${slug}][0] {
      title,
      "slug":slug.current,
      "author":author->name,
      "image":image.asset->url,
      description,
      category[]->,
      toc[]->,
      body,
      publishedAt
  },
  `,
    {
      slug,
    }
  );
};

const BlogDetails = async ({ params: { slug } }: Params) => {
  const singlePost = await getSinglePost(slug);
  return <BlogDetailsComponent postDetails={singlePost} />;
};
export default BlogDetails;
AI Update

I can see the issue! You're mixing JavaScript template literal syntax with GROQ parameters, which is causing the parsing error. In your query, you have ${slug} (JavaScript interpolation) when you should be using $slug (GROQ parameter syntax).

Here's the corrected version:

export const getSinglePost = async (
  slug: string
): Promise<PostData["data"]> => {
  const client = createClient(clientConfig);

  return await client.fetch(
    groq`
  *[_type == "post" && slug.current == $slug][0] {
      title,
      "slug":slug.current,
      "author":author->name,
      "image":image.asset->url,
      description,
      category[]->,
      toc[]->,
      body,
      publishedAt
  }
  `,
    {
      slug,
    }
  );
};

The key changes:

  1. Changed ${slug} to $slug in the GROQ query
  2. Removed the trailing comma after the closing brace (before the backtick)

When using GROQ parameters, you must use the $ syntax (not ${}). The parameter values are then passed as the second argument to client.fetch(), which you're already doing correctly with { slug }.

This approach is not only the correct syntax, but it's also much safer than string interpolation because it prevents GROQ injection attacks and handles proper escaping automatically. As the documentation notes, parameters are JSON literals that cannot contain GROQ expressions, making them safe even with user input.

Next.js 15 consideration: If you're using Next.js 15 with the App Router, be aware that route params are now promises, so your component needs to await them:

const BlogDetails = async ({ params }: Params) => {
  const { slug } = await params;  // await the params
  const singlePost = await getSinglePost(slug);
  return <BlogDetailsComponent postDetails={singlePost} />;
};

This is a breaking change in Next.js 15 that affects how dynamic route parameters are accessed.

Hi
user E
. I think it may be that comma after your projection:

      publishedAt
  },   // <-- Try removing the comma
  `,
    {
      slug,
user A
thanks this works but my data in null, it does not show
Since you want the slug
param
, it looks like you’ll want to change
${slug}
to
$slug
in this line:

*[_type == "post" && slug.current == ${slug}][0] {

It works now, many thanks
user A
. I really appreciate it. It looks like I have to learn the groq query language :simple_smile:
Great! Glad to hear it.
Here are a few resources, if you’re interested:


https://hdoro.dev/learn-groq
https://www.sanity.io/docs/how-queries-work
https://www.sanity.io/docs/query-cheat-sheet
Thank you

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?