forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update Sanity example with Live Content API
- Loading branch information
Showing
39 changed files
with
807 additions
and
408 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
"use client"; | ||
|
||
import { isCorsOriginError } from "next-sanity"; | ||
import { toast } from "sonner"; | ||
|
||
export function handleError(error: unknown) { | ||
if (isCorsOriginError(error)) { | ||
const { addOriginUrl } = error; | ||
toast.error(`Sanity Live couldn't connect`, { | ||
description: `Your origin is blocked by CORS policy`, | ||
duration: Infinity, | ||
action: addOriginUrl | ||
? { | ||
label: "Manage", | ||
onClick: () => window.open(addOriginUrl.toString(), "_blank"), | ||
} | ||
: undefined, | ||
}); | ||
} else if (error instanceof Error) { | ||
console.error(error); | ||
toast.error(error.name, { description: error.message, duration: Infinity }); | ||
} else { | ||
console.error(error); | ||
toast.error("Unknown error", { | ||
description: "Check the console for more details", | ||
duration: Infinity, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
"use client"; | ||
|
||
import { | ||
useDraftModeEnvironment, | ||
useIsPresentationTool, | ||
} from "next-sanity/hooks"; | ||
import { useRouter } from "next/navigation"; | ||
import { useEffect, useTransition } from "react"; | ||
import { toast } from "sonner"; | ||
import { disableDraftMode } from "./actions"; | ||
|
||
export default function DraftModeToast() { | ||
const isPresentationTool = useIsPresentationTool(); | ||
const env = useDraftModeEnvironment(); | ||
const router = useRouter(); | ||
const [pending, startTransition] = useTransition(); | ||
|
||
useEffect(() => { | ||
if (isPresentationTool === false) { | ||
/** | ||
* We delay the toast in case we're inside Presentation Tool | ||
*/ | ||
const toastId = toast("Draft Mode Enabled", { | ||
id: "draft-mode-toast", | ||
description: | ||
env === "live" | ||
? "Content is live, refreshing automatically" | ||
: "Refresh manually to see changes", | ||
duration: Infinity, | ||
action: { | ||
label: "Disable", | ||
onClick: () => | ||
startTransition(async () => { | ||
await disableDraftMode(); | ||
startTransition(() => router.refresh()); | ||
}), | ||
}, | ||
}); | ||
return () => { | ||
toast.dismiss(toastId); | ||
}; | ||
} | ||
}, [env, router, isPresentationTool]); | ||
|
||
useEffect(() => { | ||
if (pending) { | ||
const toastId = toast.loading("Disabling draft mode..."); | ||
return () => { | ||
toast.dismiss(toastId); | ||
}; | ||
} | ||
}, [pending]); | ||
|
||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
"use client"; | ||
|
||
import { useEffect } from "react"; | ||
import { toast } from "sonner"; | ||
import { useDeferredLayoutShift } from "./use-deferred-transition"; | ||
|
||
/** | ||
* Suspends layout shift for the hero post when a new post is published. | ||
* On changes it'll require opt-in form the user before the post is shown. | ||
* If the post itself is edited, it'll refresh automatically to allow fixing typos. | ||
*/ | ||
|
||
export function HeroLayoutShift(props: { | ||
children: React.ReactNode; | ||
id: string; | ||
}) { | ||
const [children, pending, startViewTransition] = useDeferredLayoutShift( | ||
props.children, | ||
[props.id], | ||
); | ||
|
||
/** | ||
* We need to suspend layout shift for user opt-in. | ||
*/ | ||
useEffect(() => { | ||
if (!pending) return; | ||
|
||
toast("A new post is available", { | ||
id: "hero-layout-shift", | ||
duration: Infinity, | ||
action: { | ||
label: "Refresh", | ||
onClick: () => { | ||
requestAnimationFrame(() => | ||
document | ||
.querySelector("article") | ||
?.scrollIntoView({ behavior: "smooth", block: "nearest" }), | ||
); | ||
startViewTransition(); | ||
}, | ||
}, | ||
}); | ||
}, [pending, startViewTransition]); | ||
|
||
return children; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
examples/cms-sanity/app/(blog)/more-stories-layout-shift.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
"use client"; | ||
|
||
import { useEffect } from "react"; | ||
import { toast } from "sonner"; | ||
import { useDeferredLayoutShift } from "./use-deferred-transition"; | ||
|
||
/** | ||
* Suspends layout shift for the more stories section when a new post is published. | ||
* On changes it'll require opt-in form the user before the post is shown. | ||
* If the post itself is edited, it'll refresh automatically to allow fixing typos. | ||
*/ | ||
|
||
export function MoreStoriesLayoutShift(props: { | ||
children: React.ReactNode; | ||
ids: string[]; | ||
}) { | ||
const [children, pending, startViewTransition] = useDeferredLayoutShift( | ||
props.children, | ||
props.ids, | ||
); | ||
|
||
/** | ||
* We need to suspend layout shift for user opt-in. | ||
*/ | ||
useEffect(() => { | ||
if (!pending) return; | ||
|
||
toast("More stories have been published", { | ||
id: "more-stories-layout-shift", | ||
duration: Infinity, | ||
action: { | ||
label: "Refresh", | ||
onClick: () => startViewTransition(), | ||
}, | ||
}); | ||
}, [pending, startViewTransition]); | ||
|
||
return children; | ||
} |
Oops, something went wrong.