Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Sanity example to next v15 #71640

Merged
merged 3 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/cms-sanity/app/(blog)/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { draftMode } from "next/headers";
export async function disableDraftMode() {
"use server";
await Promise.allSettled([
draftMode().disable(),
(await draftMode()).disable(),
// Simulate a delay to show the loading state
new Promise((resolve) => setTimeout(resolve, 1000)),
]);
Expand Down
82 changes: 37 additions & 45 deletions examples/cms-sanity/app/(blog)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
} from "next-sanity";
import { Inter } from "next/font/google";
import { draftMode } from "next/headers";
import { Suspense } from "react";

import AlertBanner from "./alert-banner";
import PortableText from "./portable-text";
Expand Down Expand Up @@ -56,60 +55,53 @@ const inter = Inter({
display: "swap",
});

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

return (
<footer className="bg-accent-1 border-accent-2 border-t">
<div className="container mx-auto px-5">
{footer.length > 0 ? (
<PortableText
className="prose-sm text-pretty bottom-0 w-full max-w-none bg-white py-12 text-center md:py-20"
value={footer as PortableTextBlock[]}
/>
) : (
<div className="flex flex-col items-center py-28 lg:flex-row">
<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">
Built with Next.js.
</h3>
<div className="flex flex-col items-center justify-center lg:w-1/2 lg:flex-row lg:pl-4">
<a
href="https://nextjs.org/docs"
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"
>
Read Documentation
</a>
<a
href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity"
className="mx-3 font-bold hover:underline"
>
View on GitHub
</a>
</div>
</div>
)}
</div>
</footer>
);
}

export default function RootLayout({
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const data = await sanityFetch({ query: settingsQuery });
const footer = data?.footer || [];
const { isEnabled: isDraftMode } = await draftMode();

return (
<html lang="en" className={`${inter.variable} bg-white text-black`}>
<body>
<section className="min-h-screen">
{draftMode().isEnabled && <AlertBanner />}
{isDraftMode && <AlertBanner />}
<main>{children}</main>
<Suspense>
<Footer />
</Suspense>
<footer className="bg-accent-1 border-accent-2 border-t">
<div className="container mx-auto px-5">
{footer.length > 0 ? (
<PortableText
className="prose-sm text-pretty bottom-0 w-full max-w-none bg-white py-12 text-center md:py-20"
value={footer as PortableTextBlock[]}
/>
) : (
<div className="flex flex-col items-center py-28 lg:flex-row">
<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">
Built with Next.js.
</h3>
<div className="flex flex-col items-center justify-center lg:w-1/2 lg:flex-row lg:pl-4">
<a
href="https://nextjs.org/docs"
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"
>
Read Documentation
</a>
<a
href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity"
className="mx-3 font-bold hover:underline"
>
View on GitHub
</a>
</div>
</div>
)}
</div>
</footer>
</section>
{draftMode().isEnabled && <VisualEditing />}
{isDraftMode && <VisualEditing />}
<SpeedInsights />
</body>
</html>
Expand Down
8 changes: 6 additions & 2 deletions examples/cms-sanity/app/(blog)/posts/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { postQuery, settingsQuery } from "@/sanity/lib/queries";
import { resolveOpenGraphImage } from "@/sanity/lib/utils";

type Props = {
params: { slug: string };
params: Promise<{ slug: string }>;
};

const postSlugs = defineQuery(
Expand All @@ -36,7 +36,11 @@ export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
const post = await sanityFetch({ 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 Down
8 changes: 8 additions & 0 deletions examples/cms-sanity/app/api/draft-mode/enable/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineEnableDraftMode } from "next-sanity/draft-mode";

import { client } from "@/sanity/lib/client";
import { token } from "@/sanity/lib/token";

export const { GET } = defineEnableDraftMode({
client: client.withConfig({ token }),
});
27 changes: 0 additions & 27 deletions examples/cms-sanity/app/api/draft/route.tsx

This file was deleted.

10 changes: 0 additions & 10 deletions examples/cms-sanity/next.config.js

This file was deleted.

10 changes: 10 additions & 0 deletions examples/cms-sanity/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
env: {
// 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.
SC_DISABLE_SPEEDY: "false",
},
};

export default nextConfig;
40 changes: 20 additions & 20 deletions examples/cms-sanity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"private": true,
"scripts": {
"predev": "npm run typegen",
"dev": "next",
"dev": "next --turbo",
"prebuild": "npm run typegen",
"build": "next build",
"start": "next start",
Expand All @@ -13,32 +13,32 @@
"typegen": "sanity schema extract && sanity typegen generate"
},
"dependencies": {
"@sanity/assist": "^3.0.6",
"@sanity/icons": "^3.3.1",
"@sanity/assist": "^3.0.8",
"@sanity/icons": "^3.4.0",
"@sanity/image-url": "^1.0.2",
"@sanity/preview-url-secret": "^1.6.20",
"@sanity/vision": "^3.55.0",
"@tailwindcss/typography": "^0.5.14",
"@types/node": "^20.14.13",
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.0",
"@vercel/speed-insights": "^1.0.12",
"@sanity/preview-url-secret": "^2.0.0",
"@sanity/vision": "^3.62.0",
"@tailwindcss/typography": "^0.5.15",
"@types/node": "^22.7.8",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"@vercel/speed-insights": "^1.0.13",
"autoprefixer": "^10.4.20",
"date-fns": "^3.6.0",
"next": "^14.2.5",
"next-sanity": "^9.4.7",
"postcss": "^8.4.41",
"date-fns": "^4.1.0",
"next": "^15.0.0",
"next-sanity": "^9.7.0",
"postcss": "^8.4.47",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"sanity": "^3.55.0",
"sanity": "^3.62.0",
"sanity-plugin-asset-source-unsplash": "^3.0.1",
"server-only": "^0.0.1",
"styled-components": "^6.1.12",
"tailwindcss": "^3.4.10",
"typescript": "5.5.4"
"styled-components": "^6.1.13",
"tailwindcss": "^3.4.14",
"typescript": "5.6.3"
},
"devDependencies": {
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.5"
"eslint": "^9.13.0",
"eslint-config-next": "^15.0.0"
}
}
2 changes: 1 addition & 1 deletion examples/cms-sanity/sanity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default defineConfig({
}),
},
},
previewUrl: { previewMode: { enable: "/api/draft" } },
previewUrl: { previewMode: { enable: "/api/draft-mode/enable" } },
}),
structureTool({ structure: pageStructure([settings]) }),
// Configures the global "new document" button, and document actions, to suit the Settings document singleton
Expand Down
19 changes: 13 additions & 6 deletions examples/cms-sanity/sanity/lib/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,29 @@ import { token } from "@/sanity/lib/token";
export async function sanityFetch<const QueryString extends string>({
query,
params = {},
perspective = draftMode().isEnabled ? "previewDrafts" : "published",
perspective: _perspective,
/**
* Stega embedded Content Source Maps are used by Visual Editing by both the Sanity Presentation Tool and Vercel Visual Editing.
* 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.
* 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.
*/
stega = perspective === "previewDrafts" ||
process.env.VERCEL_ENV === "preview",
stega: _stega,
}: {
query: QueryString;
params?: QueryParams;
params?: QueryParams | Promise<QueryParams>;
perspective?: Omit<ClientPerspective, "raw">;
stega?: boolean;
}) {
const perspective =
_perspective || (await draftMode()).isEnabled
? "previewDrafts"
: "published";
const stega =
_stega ||
perspective === "previewDrafts" ||
process.env.VERCEL_ENV === "preview";
if (perspective === "previewDrafts") {
return client.fetch(query, params, {
return client.fetch(query, await params, {
stega,
perspective: "previewDrafts",
// The token is required to fetch draft content
Expand All @@ -39,7 +46,7 @@ export async function sanityFetch<const QueryString extends string>({
next: { revalidate: 0 },
});
}
return client.fetch(query, params, {
return client.fetch(query, await params, {
stega,
perspective: "published",
// The `published` perspective is available on the API CDN
Expand Down
8 changes: 0 additions & 8 deletions examples/cms-sanity/sanity/lib/token.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import "server-only";

import { experimental_taintUniqueValue } from "react";

export const token = process.env.SANITY_API_READ_TOKEN;

if (!token) {
throw new Error("Missing SANITY_API_READ_TOKEN");
}

experimental_taintUniqueValue(
"Do not pass the sanity API read token to the client.",
process,
token,
);
Loading