mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
This PR updates the `cms-sanity` example to use: - App Router - TypeScript - Sanity Studio v3 instead of v2 - Embeds the Studio inside the next app on the `/studio` route. - ISR / Data Cache (revalidations through `revalidatePath` while in Live Visual Editing, time-based to match the Sanity API CDN in production). - Support Vercel Visual Editing out of the box. - The new `next-sanity/image` component. - Vercel Speed Insights. - The Sanity Presentation Tool for live content previews. - Sanity Portable Text setup to fully support `@tailwindcss/typography`. - [AI Assist](https://www.sanity.io/docs/ai-assist) - Auto fill in `alt` text on images. - Preset prompts for content creation
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { groq, type PortableTextBlock } from "next-sanity";
|
|
import type { Image } from "sanity";
|
|
|
|
export const settingsQuery = groq`*[_type == "settings"][0]`;
|
|
export interface SettingsQueryResponse {
|
|
title?: string;
|
|
description?: PortableTextBlock[];
|
|
footer?: PortableTextBlock[];
|
|
ogImage?: (Image & { alt?: string; metadataBase?: string }) | null;
|
|
}
|
|
|
|
export interface Author {
|
|
name: string;
|
|
picture?: (Image & { alt?: string | null }) | null;
|
|
}
|
|
export interface Post {
|
|
_id: string;
|
|
status: "draft" | "published";
|
|
title: string;
|
|
slug: string;
|
|
excerpt?: string | null;
|
|
coverImage?: (Image & { alt?: string }) | null;
|
|
date: string;
|
|
author?: Author | null;
|
|
}
|
|
|
|
const postFields = groq`
|
|
_id,
|
|
"status": select(_originalId in path("drafts.**") => "draft", "published"),
|
|
"title": coalesce(title, "Untitled"),
|
|
"slug": slug.current,
|
|
excerpt,
|
|
coverImage,
|
|
"date": coalesce(date, _updatedAt),
|
|
"author": author->{"name": coalesce(name, "Anonymous"), picture},
|
|
`;
|
|
|
|
export const heroQuery = groq`*[_type == "post" && defined(slug.current)] | order(date desc, _updatedAt desc) [0] {
|
|
content,
|
|
${postFields}
|
|
}`;
|
|
export type HeroQueryResponse =
|
|
| (Post & {
|
|
content?: PortableTextBlock[] | null;
|
|
})
|
|
| null;
|
|
|
|
export const moreStoriesQuery = groq`*[_type == "post" && _id != $skip && defined(slug.current)] | order(date desc, _updatedAt desc) [0...$limit] {
|
|
${postFields}
|
|
}`;
|
|
export type MoreStoriesQueryResponse = Post[] | null;
|
|
|
|
export const postQuery = groq`*[_type == "post" && slug.current == $slug] [0] {
|
|
content,
|
|
${postFields}
|
|
}`;
|
|
export type PostQueryResponse =
|
|
| (Post & {
|
|
content?: PortableTextBlock[] | null;
|
|
})
|
|
| null;
|