Lesson
4
Render pages
Create a new dynamic route to render "page" documents and create links to them within Sanity Studio for an interactive live preview within Presentation.
Log in to mark your progress for each Lesson and Task
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.
Update the file with all your queries to include one for an individual page:
src/sanity/lib/queries.ts
// ...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
This command was setup in the Generate TypeScript Types lesson of the Content-driven web application foundations course.
Before rendering individual blocks, the Next.js application needs a route to render any individual page.
Create a new route for rendering any page document by its unique slug.
src/app/(frontend)/[slug]/page.tsx
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.
Update the document locations resolver
src/sanity/presentation/resolve.ts
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.
You have 3 uncompleted tasks in this lesson
0 of 3