Skip to content

Commit

Permalink
examples: Improve TypeGen in Sanity Example (vercel#68580)
Browse files Browse the repository at this point in the history
Uses the improved TypeGen just released in `sanity`
[v3.53.0](https://github.com/sanity-io/sanity/releases/tag/v3.53.0) 🥳
  • Loading branch information
stipsan authored Aug 15, 2024
1 parent 5223c92 commit b944143
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 59 deletions.
7 changes: 2 additions & 5 deletions examples/cms-sanity/app/(blog)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ import { Suspense } from "react";
import AlertBanner from "./alert-banner";
import PortableText from "./portable-text";

import type { SettingsQueryResult } from "@/sanity.types";
import * as demo from "@/sanity/lib/demo";
import { sanityFetch } from "@/sanity/lib/fetch";
import { settingsQuery } from "@/sanity/lib/queries";
import { resolveOpenGraphImage } from "@/sanity/lib/utils";

export async function generateMetadata(): Promise<Metadata> {
const settings = await sanityFetch<SettingsQueryResult>({
const settings = await sanityFetch({
query: settingsQuery,
// Metadata should never contain stega
stega: false,
Expand Down Expand Up @@ -58,9 +57,7 @@ const inter = Inter({
});

async function Footer() {
const data = await sanityFetch<SettingsQueryResult>({
query: settingsQuery,
});
const data = await sanityFetch({ query: settingsQuery });
const footer = data?.footer || [];

return (
Expand Down
6 changes: 1 addition & 5 deletions examples/cms-sanity/app/(blog)/more-stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,14 @@ import Avatar from "./avatar";
import CoverImage from "./cover-image";
import DateComponent from "./date";

import type { MoreStoriesQueryResult } from "@/sanity.types";
import { sanityFetch } from "@/sanity/lib/fetch";
import { moreStoriesQuery } from "@/sanity/lib/queries";

export default async function MoreStories(params: {
skip: string;
limit: number;
}) {
const data = await sanityFetch<MoreStoriesQueryResult>({
query: moreStoriesQuery,
params,
});
const data = await sanityFetch({ query: moreStoriesQuery, params });

return (
<>
Expand Down
30 changes: 9 additions & 21 deletions examples/cms-sanity/app/(blog)/posts/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineQuery } from "groq";
import type { Metadata, ResolvingMetadata } from "next";
import { groq, type PortableTextBlock } from "next-sanity";
import { type PortableTextBlock } from "next-sanity";
import Link from "next/link";
import { notFound } from "next/navigation";
import { Suspense } from "react";
Expand All @@ -10,11 +11,6 @@ import DateComponent from "../../date";
import MoreStories from "../../more-stories";
import PortableText from "../../portable-text";

import type {
PostQueryResult,
PostSlugsResult,
SettingsQueryResult,
} from "@/sanity.types";
import * as demo from "@/sanity/lib/demo";
import { sanityFetch } from "@/sanity/lib/fetch";
import { postQuery, settingsQuery } from "@/sanity/lib/queries";
Expand All @@ -24,26 +20,23 @@ type Props = {
params: { slug: string };
};

const postSlugs = groq`*[_type == "post"]{slug}`;
const postSlugs = defineQuery(
`*[_type == "post" && defined(slug.current)]{"slug": slug.current}`,
);

export async function generateStaticParams() {
const params = await sanityFetch<PostSlugsResult>({
return await sanityFetch({
query: postSlugs,
perspective: "published",
stega: false,
});
return params.map(({ slug }) => ({ slug: slug?.current }));
}

export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
const post = await sanityFetch<PostQueryResult>({
query: postQuery,
params,
stega: false,
});
const post = await sanityFetch({ query: postQuery, params, stega: false });
const previousImages = (await parent).openGraph?.images || [];
const ogImage = resolveOpenGraphImage(post?.coverImage);

Expand All @@ -59,13 +52,8 @@ export async function generateMetadata(

export default async function PostPage({ params }: Props) {
const [post, settings] = await Promise.all([
sanityFetch<PostQueryResult>({
query: postQuery,
params,
}),
sanityFetch<SettingsQueryResult>({
query: settingsQuery,
}),
sanityFetch({ query: postQuery, params }),
sanityFetch({ query: settingsQuery }),
]);

if (!post?._id) {
Expand Down
11 changes: 6 additions & 5 deletions examples/cms-sanity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,22 @@
"@sanity/assist": "^3.0.5",
"@sanity/icons": "^3.3.1",
"@sanity/image-url": "^1.0.2",
"@sanity/preview-url-secret": "^1.6.18",
"@sanity/vision": "^3.52.4",
"@sanity/preview-url-secret": "^1.6.19",
"@sanity/vision": "^3.53.0",
"@tailwindcss/typography": "^0.5.13",
"@types/node": "^20.14.13",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vercel/speed-insights": "^1.0.12",
"autoprefixer": "^10.4.19",
"autoprefixer": "^10.4.20",
"date-fns": "^3.6.0",
"groq": "^3.53.0",
"next": "^14.2.5",
"next-sanity": "^9.4.3",
"postcss": "^8.4.40",
"postcss": "^8.4.41",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"sanity": "^3.52.4",
"sanity": "^3.53.0",
"sanity-plugin-asset-source-unsplash": "^3.0.1",
"server-only": "^0.0.1",
"styled-components": "^6.1.12",
Expand Down
1 change: 1 addition & 0 deletions examples/cms-sanity/sanity-typegen.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "overloadClientMethods": true }
26 changes: 20 additions & 6 deletions examples/cms-sanity/sanity.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ export type SettingsQueryResult = {
};
} | null;
// Variable: heroQuery
// Query: *[_type == "post" && defined(slug.current)] | order(date desc, _updatedAt desc) [0] { content, _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},}
// Query: *[_type == "post" && defined(slug.current)] | order(date desc, _updatedAt desc) [0] { content, _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 type HeroQueryResult = {
content: Array<{
children?: Array<{
Expand Down Expand Up @@ -537,7 +537,7 @@ export type HeroQueryResult = {
} | null;
} | null;
// Variable: moreStoriesQuery
// Query: *[_type == "post" && _id != $skip && defined(slug.current)] | order(date desc, _updatedAt desc) [0...$limit] { _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},}
// Query: *[_type == "post" && _id != $skip && defined(slug.current)] | order(date desc, _updatedAt desc) [0...$limit] { _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 type MoreStoriesQueryResult = Array<{
_id: string;
status: "draft" | "published";
Expand Down Expand Up @@ -574,7 +574,7 @@ export type MoreStoriesQueryResult = Array<{
} | null;
}>;
// Variable: postQuery
// Query: *[_type == "post" && slug.current == $slug] [0] { content, _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},}
// Query: *[_type == "post" && slug.current == $slug] [0] { content, _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 type PostQueryResult = {
content: Array<{
children?: Array<{
Expand Down Expand Up @@ -628,9 +628,23 @@ export type PostQueryResult = {
} | null;
} | null;
} | null;
// Source: ./app/(blog)/posts/[slug]/page.tsx
import "@sanity/client";
declare module "@sanity/client" {
interface SanityQueries {
'*[_type == "settings"][0]': SettingsQueryResult;
'\n *[_type == "post" && defined(slug.current)] | order(date desc, _updatedAt desc) [0] {\n content,\n \n _id,\n "status": select(_originalId in path("drafts.**") => "draft", "published"),\n "title": coalesce(title, "Untitled"),\n "slug": slug.current,\n excerpt,\n coverImage,\n "date": coalesce(date, _updatedAt),\n "author": author->{"name": coalesce(name, "Anonymous"), picture},\n\n }\n': HeroQueryResult;
'\n *[_type == "post" && _id != $skip && defined(slug.current)] | order(date desc, _updatedAt desc) [0...$limit] {\n \n _id,\n "status": select(_originalId in path("drafts.**") => "draft", "published"),\n "title": coalesce(title, "Untitled"),\n "slug": slug.current,\n excerpt,\n coverImage,\n "date": coalesce(date, _updatedAt),\n "author": author->{"name": coalesce(name, "Anonymous"), picture},\n\n }\n': MoreStoriesQueryResult;
'\n *[_type == "post" && slug.current == $slug] [0] {\n content,\n \n _id,\n "status": select(_originalId in path("drafts.**") => "draft", "published"),\n "title": coalesce(title, "Untitled"),\n "slug": slug.current,\n excerpt,\n coverImage,\n "date": coalesce(date, _updatedAt),\n "author": author->{"name": coalesce(name, "Anonymous"), picture},\n\n }\n': PostQueryResult;
}
} // Source: ./app/(blog)/posts/[slug]/page.tsx
// Variable: postSlugs
// Query: *[_type == "post"]{slug}
// Query: *[_type == "post" && defined(slug.current)]{"slug": slug.current}
export type PostSlugsResult = Array<{
slug: Slug | null;
slug: string | null;
}>;
import "@sanity/client";
declare module "@sanity/client" {
interface SanityQueries {
'*[_type == "post" && defined(slug.current)]{"slug": slug.current}': PostSlugsResult;
}
}
8 changes: 4 additions & 4 deletions examples/cms-sanity/sanity/lib/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { token } from "@/sanity/lib/token";
* and will also fetch from the CDN.
* When using the "previewDrafts" perspective then the data is fetched from the live API and isn't cached, it will also fetch draft content that isn't published yet.
*/
export async function sanityFetch<QueryResponse>({
export async function sanityFetch<const QueryString extends string>({
query,
params = {},
perspective = draftMode().isEnabled ? "previewDrafts" : "published",
Expand All @@ -22,13 +22,13 @@ export async function sanityFetch<QueryResponse>({
stega = perspective === "previewDrafts" ||
process.env.VERCEL_ENV === "preview",
}: {
query: string;
query: QueryString;
params?: QueryParams;
perspective?: Omit<ClientPerspective, "raw">;
stega?: boolean;
}) {
if (perspective === "previewDrafts") {
return client.fetch<QueryResponse>(query, params, {
return client.fetch(query, params, {
stega,
perspective: "previewDrafts",
// The token is required to fetch draft content
Expand All @@ -39,7 +39,7 @@ export async function sanityFetch<QueryResponse>({
next: { revalidate: 0 },
});
}
return client.fetch<QueryResponse>(query, params, {
return client.fetch(query, params, {
stega,
perspective: "published",
// The `published` perspective is available on the API CDN
Expand Down
32 changes: 19 additions & 13 deletions examples/cms-sanity/sanity/lib/queries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { groq } from "next-sanity";
import { defineQuery } from "groq";

export const settingsQuery = groq`*[_type == "settings"][0]`;
export const settingsQuery = defineQuery(`*[_type == "settings"][0]`);

const postFields = /* groq */ `
_id,
Expand All @@ -13,16 +13,22 @@ const postFields = /* groq */ `
"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 const heroQuery = defineQuery(`
*[_type == "post" && defined(slug.current)] | order(date desc, _updatedAt desc) [0] {
content,
${postFields}
}
`);

export const moreStoriesQuery = groq`*[_type == "post" && _id != $skip && defined(slug.current)] | order(date desc, _updatedAt desc) [0...$limit] {
${postFields}
}`;
export const moreStoriesQuery = defineQuery(`
*[_type == "post" && _id != $skip && defined(slug.current)] | order(date desc, _updatedAt desc) [0...$limit] {
${postFields}
}
`);

export const postQuery = groq`*[_type == "post" && slug.current == $slug] [0] {
content,
${postFields}
}`;
export const postQuery = defineQuery(`
*[_type == "post" && slug.current == $slug] [0] {
content,
${postFields}
}
`);

0 comments on commit b944143

Please sign in to comment.