-
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathvisual-editing.ts
More file actions
87 lines (78 loc) · 2.81 KB
/
Copy pathvisual-editing.ts
File metadata and controls
87 lines (78 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
* Sanity Visual Editing (Plain JS) — minimal integration per official docs.
* https://reference.sanity.io/_sanity/visual-editing/
*
* History update uses pushState/replaceState only so the Studio can drive
* iframe navigation (e.g. by loading the preview URL when you click locations).
* We only handle presentation/perspective so perspective switches reload with the right param.
*/
import { enableVisualEditing } from "@sanity/visual-editing";
function subscribeToPerspectiveChanges(): () => void {
const studioOrigin =
typeof import.meta.env.PUBLIC_SANITY_STUDIO_URL === "string"
? new URL(import.meta.env.PUBLIC_SANITY_STUDIO_URL).origin
: null;
const handler = (event: MessageEvent) => {
if (studioOrigin && event.origin !== studioOrigin) return;
const type = event.data?.type;
const data = event.data?.data;
if (type !== "presentation/perspective" || data == null) return;
const perspective = data.perspective;
if (perspective == null) return;
const value =
typeof perspective === "string"
? perspective
: Array.isArray(perspective)
? perspective.join(",")
: String(perspective);
const url = new URL(window.location.href);
url.searchParams.set("sanity-preview-perspective", value);
window.location.replace(url.toString());
};
window.addEventListener("message", handler);
return () => window.removeEventListener("message", handler);
}
export function run(): () => void {
const teardownPerspective = subscribeToPerspectiveChanges();
const teardownVisualEditing = enableVisualEditing({
history: {
subscribe: (navigate) => {
const handler = (_event: PopStateEvent) => {
navigate({
type: "push",
url: `${location.pathname}${location.search}`,
});
};
window.addEventListener("popstate", handler);
return () => window.removeEventListener("popstate", handler);
},
update: (update) => {
switch (update.type) {
case "push":
window.history.pushState(null, "", update.url);
break;
case "pop":
window.history.back();
break;
case "replace":
window.history.replaceState(null, "", update.url);
break;
default:
throw new Error(`Unknown update type: ${(update as { type: string }).type}`);
}
},
},
zIndex: 1000,
// Let default behavior apply: manual = reload, mutation = no default for Plain JS
refresh: async (payload) => {
if (payload.source === "manual") {
window.location.reload();
}
// source === 'mutation': no default for Plain JS per docs; don't reload unless you want to
},
});
return () => {
teardownPerspective();
teardownVisualEditing();
};
}