Skip to content

Commit 0d5e982

Browse files
committed
Update Sanity example to next v15
1 parent 26085c4 commit 0d5e982

File tree

11 files changed

+87
-111
lines changed

11 files changed

+87
-111
lines changed

examples/cms-sanity/app/(blog)/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { draftMode } from "next/headers";
55
export async function disableDraftMode() {
66
"use server";
77
await Promise.allSettled([
8-
draftMode().disable(),
8+
(await draftMode()).disable(),
99
// Simulate a delay to show the loading state
1010
new Promise((resolve) => setTimeout(resolve, 1000)),
1111
]);

examples/cms-sanity/app/(blog)/layout.tsx

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
} from "next-sanity";
1010
import { Inter } from "next/font/google";
1111
import { draftMode } from "next/headers";
12-
import { Suspense } from "react";
1312

1413
import AlertBanner from "./alert-banner";
1514
import PortableText from "./portable-text";
@@ -56,60 +55,53 @@ const inter = Inter({
5655
display: "swap",
5756
});
5857

59-
async function Footer() {
60-
const data = await sanityFetch({ query: settingsQuery });
61-
const footer = data?.footer || [];
62-
63-
return (
64-
<footer className="bg-accent-1 border-accent-2 border-t">
65-
<div className="container mx-auto px-5">
66-
{footer.length > 0 ? (
67-
<PortableText
68-
className="prose-sm text-pretty bottom-0 w-full max-w-none bg-white py-12 text-center md:py-20"
69-
value={footer as PortableTextBlock[]}
70-
/>
71-
) : (
72-
<div className="flex flex-col items-center py-28 lg:flex-row">
73-
<h3 className="mb-10 text-center text-4xl font-bold leading-tight tracking-tighter lg:mb-0 lg:w-1/2 lg:pr-4 lg:text-left lg:text-5xl">
74-
Built with Next.js.
75-
</h3>
76-
<div className="flex flex-col items-center justify-center lg:w-1/2 lg:flex-row lg:pl-4">
77-
<a
78-
href="https://nextjs.org/docs"
79-
className="mx-3 mb-6 border border-black bg-black py-3 px-12 font-bold text-white transition-colors duration-200 hover:bg-white hover:text-black lg:mb-0 lg:px-8"
80-
>
81-
Read Documentation
82-
</a>
83-
<a
84-
href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity"
85-
className="mx-3 font-bold hover:underline"
86-
>
87-
View on GitHub
88-
</a>
89-
</div>
90-
</div>
91-
)}
92-
</div>
93-
</footer>
94-
);
95-
}
96-
97-
export default function RootLayout({
58+
export default async function RootLayout({
9859
children,
9960
}: {
10061
children: React.ReactNode;
10162
}) {
63+
const data = await sanityFetch({ query: settingsQuery });
64+
const footer = data?.footer || [];
65+
const { isEnabled: isDraftMode } = await draftMode();
66+
10267
return (
10368
<html lang="en" className={`${inter.variable} bg-white text-black`}>
10469
<body>
10570
<section className="min-h-screen">
106-
{draftMode().isEnabled && <AlertBanner />}
71+
{isDraftMode && <AlertBanner />}
10772
<main>{children}</main>
108-
<Suspense>
109-
<Footer />
110-
</Suspense>
73+
<footer className="bg-accent-1 border-accent-2 border-t">
74+
<div className="container mx-auto px-5">
75+
{footer.length > 0 ? (
76+
<PortableText
77+
className="prose-sm text-pretty bottom-0 w-full max-w-none bg-white py-12 text-center md:py-20"
78+
value={footer as PortableTextBlock[]}
79+
/>
80+
) : (
81+
<div className="flex flex-col items-center py-28 lg:flex-row">
82+
<h3 className="mb-10 text-center text-4xl font-bold leading-tight tracking-tighter lg:mb-0 lg:w-1/2 lg:pr-4 lg:text-left lg:text-5xl">
83+
Built with Next.js.
84+
</h3>
85+
<div className="flex flex-col items-center justify-center lg:w-1/2 lg:flex-row lg:pl-4">
86+
<a
87+
href="https://nextjs.org/docs"
88+
className="mx-3 mb-6 border border-black bg-black py-3 px-12 font-bold text-white transition-colors duration-200 hover:bg-white hover:text-black lg:mb-0 lg:px-8"
89+
>
90+
Read Documentation
91+
</a>
92+
<a
93+
href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity"
94+
className="mx-3 font-bold hover:underline"
95+
>
96+
View on GitHub
97+
</a>
98+
</div>
99+
</div>
100+
)}
101+
</div>
102+
</footer>
111103
</section>
112-
{draftMode().isEnabled && <VisualEditing />}
104+
{isDraftMode && <VisualEditing />}
113105
<SpeedInsights />
114106
</body>
115107
</html>

examples/cms-sanity/app/(blog)/posts/[slug]/page.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { postQuery, settingsQuery } from "@/sanity/lib/queries";
1717
import { resolveOpenGraphImage } from "@/sanity/lib/utils";
1818

1919
type Props = {
20-
params: { slug: string };
20+
params: Promise<{ slug: string }>;
2121
};
2222

2323
const postSlugs = defineQuery(
@@ -36,7 +36,11 @@ export async function generateMetadata(
3636
{ params }: Props,
3737
parent: ResolvingMetadata,
3838
): Promise<Metadata> {
39-
const post = await sanityFetch({ query: postQuery, params, stega: false });
39+
const post = await sanityFetch({
40+
query: postQuery,
41+
params,
42+
stega: false,
43+
});
4044
const previousImages = (await parent).openGraph?.images || [];
4145
const ogImage = resolveOpenGraphImage(post?.coverImage);
4246

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineEnableDraftMode } from "next-sanity/draft-mode";
2+
3+
import { client } from "@/sanity/lib/client";
4+
import { token } from "@/sanity/lib/token";
5+
6+
export const { GET } = defineEnableDraftMode({
7+
client: client.withConfig({ token }),
8+
});

examples/cms-sanity/app/api/draft/route.tsx

Lines changed: 0 additions & 27 deletions
This file was deleted.

examples/cms-sanity/next.config.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

examples/cms-sanity/next.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { NextConfig } from "next";
2+
3+
const nextConfig: NextConfig = {
4+
env: {
5+
// Matches the behavior of `sanity dev` which sets styled-components to use the fastest way of inserting CSS rules in both dev and production. It's default behavior is to disable it in dev mode.
6+
SC_DISABLE_SPEEDY: "false",
7+
},
8+
};
9+
10+
export default nextConfig;

examples/cms-sanity/package.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"private": true,
33
"scripts": {
44
"predev": "npm run typegen",
5-
"dev": "next",
5+
"dev": "next --turbo",
66
"prebuild": "npm run typegen",
77
"build": "next build",
88
"start": "next start",
@@ -16,29 +16,29 @@
1616
"@sanity/assist": "^3.0.8",
1717
"@sanity/icons": "^3.4.0",
1818
"@sanity/image-url": "^1.0.2",
19-
"@sanity/preview-url-secret": "^1.6.21",
20-
"@sanity/vision": "^3.60.0",
19+
"@sanity/preview-url-secret": "^2.0.0",
20+
"@sanity/vision": "^3.62.0",
2121
"@tailwindcss/typography": "^0.5.15",
22-
"@types/node": "^20.14.13",
22+
"@types/node": "^22.7.8",
2323
"@types/react": "^18.3.11",
2424
"@types/react-dom": "^18.3.1",
25-
"@vercel/speed-insights": "^1.0.12",
25+
"@vercel/speed-insights": "^1.0.13",
2626
"autoprefixer": "^10.4.20",
2727
"date-fns": "^4.1.0",
28-
"next": "^14.2.15",
29-
"next-sanity": "^9.5.0",
28+
"next": "^15.0.0",
29+
"next-sanity": "^9.7.0",
3030
"postcss": "^8.4.47",
3131
"react": "^18.3.1",
3232
"react-dom": "^18.3.1",
33-
"sanity": "^3.60.0",
33+
"sanity": "^3.62.0",
3434
"sanity-plugin-asset-source-unsplash": "^3.0.1",
3535
"server-only": "^0.0.1",
3636
"styled-components": "^6.1.13",
37-
"tailwindcss": "^3.4.13",
37+
"tailwindcss": "^3.4.14",
3838
"typescript": "5.6.3"
3939
},
4040
"devDependencies": {
41-
"eslint": "^8.57.0",
42-
"eslint-config-next": "^14.2.15"
41+
"eslint": "^9.13.0",
42+
"eslint-config-next": "^15.0.0"
4343
}
4444
}

examples/cms-sanity/sanity.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export default defineConfig({
7171
}),
7272
},
7373
},
74-
previewUrl: { previewMode: { enable: "/api/draft" } },
74+
previewUrl: { previewMode: { enable: "/api/draft-mode/enable" } },
7575
}),
7676
structureTool({ structure: pageStructure([settings]) }),
7777
// Configures the global "new document" button, and document actions, to suit the Settings document singleton

examples/cms-sanity/sanity/lib/fetch.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,29 @@ import { token } from "@/sanity/lib/token";
1313
export async function sanityFetch<const QueryString extends string>({
1414
query,
1515
params = {},
16-
perspective = draftMode().isEnabled ? "previewDrafts" : "published",
16+
perspective: _perspective,
1717
/**
1818
* Stega embedded Content Source Maps are used by Visual Editing by both the Sanity Presentation Tool and Vercel Visual Editing.
1919
* The Sanity Presentation Tool will enable Draft Mode when loading up the live preview, and we use it as a signal for when to embed source maps.
2020
* When outside of the Sanity Studio we also support the Vercel Toolbar Visual Editing feature, which is only enabled in production when it's a Vercel Preview Deployment.
2121
*/
22-
stega = perspective === "previewDrafts" ||
23-
process.env.VERCEL_ENV === "preview",
22+
stega: _stega,
2423
}: {
2524
query: QueryString;
26-
params?: QueryParams;
25+
params?: QueryParams | Promise<QueryParams>;
2726
perspective?: Omit<ClientPerspective, "raw">;
2827
stega?: boolean;
2928
}) {
29+
const perspective =
30+
_perspective || (await draftMode()).isEnabled
31+
? "previewDrafts"
32+
: "published";
33+
const stega =
34+
_stega ||
35+
perspective === "previewDrafts" ||
36+
process.env.VERCEL_ENV === "preview";
3037
if (perspective === "previewDrafts") {
31-
return client.fetch(query, params, {
38+
return client.fetch(query, await params, {
3239
stega,
3340
perspective: "previewDrafts",
3441
// The token is required to fetch draft content
@@ -39,7 +46,7 @@ export async function sanityFetch<const QueryString extends string>({
3946
next: { revalidate: 0 },
4047
});
4148
}
42-
return client.fetch(query, params, {
49+
return client.fetch(query, await params, {
4350
stega,
4451
perspective: "published",
4552
// The `published` perspective is available on the API CDN

0 commit comments

Comments
 (0)