如何在Next.js的getServerSideProps中用查询参数作为Sanity GROQ变量
解决Next.js getServerSideProps中Sanity GROQ查询变量未提供的问题
问题场景
在博客项目实现搜索功能时,在Next.js的getServerSideProps中使用Sanity GROQ查询并引入变量$search,出现以下错误:
Server Error
ClientError: param $search referenced, but not provided
但将$search替换为实际字符串时,能正常获取查询结果。相关代码如下:
import React from 'react' import { useRouter } from 'next/router' import type { NextPage } from 'next' import Head from 'next/head' import Image from 'next/image' import Banner from '../../components/Banner' import Header from '../../components/Header' import { sanityClient,urlFor } from '../../sanity' import { Post } from '../../typings' import PostCard from '../../components/Post' import Footer from '../../components/Footer' import BottomNav from '../../components/BottomNav' interface Props{ posts:[Post]; } export default function Search({ posts}:Props) { return ( <> <div className='max-w-6xl mx-auto container-fix md:mb-1 '> <Head> <title>Const - Read for free</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <Header/> <Banner/> <PostCard posts={posts} /> <Footer/> </div> <BottomNav /> </> ) } export const getServerSideProps = async(context:any)=>{ const search = context.query.url; const query = ` *[_type=="post" && title == $search]{ _id, title, author -> { name, image, }, _createdAt, description, mainImage, category, slug }`; const posts = await sanityClient.fetch(query); return { props:{ posts } } }
解决方案
问题核心是调用sanityClient.fetch()时,仅传入了查询语句,未传递查询中引用的变量参数。Sanity的fetch方法需要第二个参数来传递变量映射对象,修改getServerSideProps中的fetch调用即可:
export const getServerSideProps = async(context:any)=>{ const search = context.query.url; const query = ` *[_type=="post" && title == $search]{ _id, title, author -> { name, image, }, _createdAt, description, mainImage, category, slug }`; // 传入变量对象,将查询中的$search与对应值绑定 const posts = await sanityClient.fetch(query, { search }); return { props:{ posts } } }
额外注意事项:
- 确认
context.query.url能正确获取到前端传入的搜索关键词,若URL查询参数名为search,需改为context.query.search - 若需要模糊匹配标题,可将GROQ查询中的
==改为contains(title, $search)或match(title, $search),提升搜索体验
内容的提问来源于stack exchange,提问作者Tejender Kumar
相关产品推荐
相关产品推荐

