Render pages
You've created your perfect schema, improved your editorial experience by adding thumbnails and now it's time to get your page builder blocks wired up on the frontend.
Now that you've created "page" type documents in the Studio, you'll need the Next.js application to query them at a dynamic route.
By the end of this chapter, you'll be able to:
- Query for and render any page by its slug
You are going to create a query to fetch the page and its page builder content from the Content Lake.
Let's break down what's happening in this query.
The ->
operator in Sanity is used for dereferencing documents. When you have a reference to another document (like our FAQs), by default you only get the reference ID. Adding ->
tells Sanity to "follow" that reference and include the full content of the referenced document in your query results. This is particularly useful when you need the actual content immediately and want to avoid making multiple separate queries.
// ...all other queries
export const PAGE_QUERY = defineQuery(`*[_type == "page" && slug.current == $slug][0]{ ..., content[]{ ..., _type == "faqs" => { ..., faqs[]-> } }}`);
This query also demonstrates a shorthand syntax of the GROQ function select()
, by which you can handle individual blocks differently by checking their _type
.
Since you've changed schema types and queries, it's time to regenerate Types as well.
npm run typegen
Before rendering individual blocks, the Next.js application needs a route to render any individual page.
import { sanityFetch } from "@/sanity/lib/live";import { PAGE_QUERY } from "@/sanity/lib/queries";
export default async function Page({ params,}: { params: Promise<{ slug: string }>;}) { const { data: page } = await sanityFetch({ query: PAGE_QUERY, params: await params, });
return <div>{JSON.stringify(page)}</div>;}
To create a link between your Sanity Studio documents and their locations in the front-end, update the resolve function created for your Presentation tool to generate dynamic links to your live preview.
import { defineLocations, PresentationPluginOptions,} from "sanity/presentation";
export const resolve: PresentationPluginOptions["resolve"] = { locations: { // ...other locations page: defineLocations({ select: { title: "title", slug: "slug.current", }, resolve: (doc) => ({ locations: [ { title: doc?.title || "Untitled", href: `/${doc?.slug}`, }, ], }), }), },};
You should now be able to open any page in Presentation by clicking the "Used on one page" link at the top of the document editor.
Now you can create pages in Sanity Studio and preview them live in the Presentation tool. The next step is to render each block as a unique component.