@prismicio/svelte 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -44,7 +44,6 @@ export let node;
44
44
  <span class={node.data.label}><slot /></span>
45
45
  {:else}
46
46
  {#each node.text.split("\n") as line, index}
47
- <!-- This formatting is intentional to prevent unwanted whitespace between elements. -->
48
47
  {#if index > 0}<br />{/if}{line}
49
48
  {/each}
50
49
  {/if}
@@ -1,27 +1,62 @@
1
1
  <script>import { onMount } from "svelte";
2
2
  import { getToolbarSrc } from "@prismicio/client";
3
- import { invalidateAll } from "$app/navigation";
3
+ import { beforeNavigate, goto, invalidateAll } from "$app/navigation";
4
4
  export let repositoryName;
5
+ export let routePrefix = "preview";
6
+ export let routePrefixName = routePrefix;
5
7
  $:
6
8
  toolbarSrc = getToolbarSrc(repositoryName);
7
- function prismicPreviewEventHandler(event) {
8
- event.preventDefault();
9
- invalidateAll();
10
- }
9
+ let endingPreview = false;
11
10
  onMount(() => {
12
- window.addEventListener("prismicPreviewUpdate", prismicPreviewEventHandler);
13
- window.addEventListener("prismicPreviewEnd", prismicPreviewEventHandler);
11
+ const controller = new AbortController();
12
+ window.addEventListener(
13
+ "prismicPreviewUpdate",
14
+ (event) => {
15
+ event.preventDefault();
16
+ invalidateAll();
17
+ },
18
+ { signal: controller.signal }
19
+ );
20
+ window.addEventListener(
21
+ "prismicPreviewEnd",
22
+ (event) => {
23
+ event.preventDefault();
24
+ endingPreview = true;
25
+ goto(
26
+ new URL(
27
+ window.location.pathname.replace(
28
+ new RegExp(`^(/${routePrefix}/?$|/${routePrefix}/)`),
29
+ "/"
30
+ ),
31
+ window.location.origin
32
+ ),
33
+ {
34
+ invalidateAll: true,
35
+ noScroll: true
36
+ }
37
+ );
38
+ },
39
+ { signal: controller.signal }
40
+ );
14
41
  return () => {
15
- window.removeEventListener(
16
- "prismicPreviewUpdate",
17
- prismicPreviewEventHandler
18
- );
19
- window.removeEventListener(
20
- "prismicPreviewEnd",
21
- prismicPreviewEventHandler
22
- );
42
+ controller.abort();
23
43
  };
24
44
  });
45
+ beforeNavigate((navigation) => {
46
+ if (navigation.to && navigation.from?.params?.[routePrefixName] === routePrefix && !(routePrefixName in (navigation.to.params || {}))) {
47
+ if (endingPreview) {
48
+ endingPreview = false;
49
+ return;
50
+ }
51
+ navigation.cancel();
52
+ goto(
53
+ new URL(
54
+ routePrefix + navigation.to.url.pathname,
55
+ navigation.to.url.origin
56
+ )
57
+ );
58
+ }
59
+ });
25
60
  </script>
26
61
 
27
62
  <svelte:head>
@@ -5,6 +5,16 @@ declare const __propDef: {
5
5
  * The name of your Prismic repository. A Prismic Toolbar will be registered
6
6
  * using this repository.
7
7
  */ repositoryName: string;
8
+ /**
9
+ * The route parameter prefixed during preview sessions.
10
+ */ routePrefix?: string | undefined;
11
+ /**
12
+ * The name of the preview-specific route parameter prefixed during preview
13
+ * sessions.
14
+ *
15
+ * Only set this value if the route parameter's name differs from the
16
+ * parameter's value.
17
+ */ routePrefixName?: string | undefined;
8
18
  };
9
19
  events: {
10
20
  [evt: string]: CustomEvent<any>;
@@ -1,4 +1,5 @@
1
1
  import * as prismic from "@prismicio/client";
2
+ import { Cookies } from "@sveltejs/kit";
2
3
  export type RedirectToPreviewURLConfig = {
3
4
  /**
4
5
  * The Prismic client configured for the preview session's repository.
@@ -10,11 +11,21 @@ export type RedirectToPreviewURLConfig = {
10
11
  * @see SvelteKit `+server` docs: \<https://kit.svelte.dev/docs/routing#server\>
11
12
  */
12
13
  request: Request;
14
+ /**
15
+ * The `cookies` object from a `+server` file.
16
+ *
17
+ * @see SvelteKit `+server` docs: \<https://kit.svelte.dev/docs/routing#server\>
18
+ */
19
+ cookies: Cookies;
13
20
  /**
14
21
  * The default redirect URL if a URL cannot be determined for the previewed
15
22
  * document.
16
23
  */
17
24
  defaultURL?: string;
25
+ /**
26
+ * The route parameter prefixed during preview sessions.
27
+ */
28
+ routePrefix?: string;
18
29
  };
19
30
  /**
20
31
  * Redirects a visitor to the URL of a previewed Prismic document from within a
@@ -1,3 +1,4 @@
1
+ import * as prismic from "@prismicio/client";
1
2
  /**
2
3
  * Redirects a visitor to the URL of a previewed Prismic document from within a
3
4
  * SvelteKit `+server` file.
@@ -20,15 +21,24 @@
20
21
  export const redirectToPreviewURL = async (config) => {
21
22
  const previewToken = new URL(config.request.url).searchParams.get("token") ?? undefined;
22
23
  const documentID = new URL(config.request.url).searchParams.get("documentId") ?? undefined;
24
+ const routePrefix = config.routePrefix ?? "preview";
23
25
  const previewURL = await config.client.resolvePreviewURL({
24
26
  previewToken,
25
27
  documentID,
26
28
  defaultURL: config.defaultURL || "/",
27
29
  });
30
+ // Prevent a flash of non-preview content by setting the preview token
31
+ // on the initial page load.
32
+ if (previewToken) {
33
+ config.cookies.set(prismic.cookie.preview, previewToken, {
34
+ path: "/",
35
+ httpOnly: false,
36
+ });
37
+ }
28
38
  return new Response(undefined, {
29
39
  status: 307,
30
40
  headers: {
31
- Location: previewURL,
41
+ Location: "/" + routePrefix + previewURL,
32
42
  },
33
43
  });
34
44
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismicio/svelte",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Svelte components to present Prismic content.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -48,7 +48,6 @@
48
48
  <span class={node.data.label}><slot /></span>
49
49
  {:else}
50
50
  {#each node.text.split("\n") as line, index}
51
- <!-- This formatting is intentional to prevent unwanted whitespace between elements. -->
52
51
  {#if index > 0}<br />{/if}{line}
53
52
  {/each}
54
53
  {/if}
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from "svelte";
3
3
  import { getToolbarSrc } from "@prismicio/client";
4
- import { invalidateAll } from "$app/navigation";
4
+ import { beforeNavigate, goto, invalidateAll } from "$app/navigation";
5
5
 
6
6
  /**
7
7
  * The name of your Prismic repository. A Prismic Toolbar will be registered
@@ -9,29 +9,94 @@
9
9
  */
10
10
  export let repositoryName: string;
11
11
 
12
- $: toolbarSrc = getToolbarSrc(repositoryName);
12
+ /**
13
+ * The route parameter prefixed during preview sessions.
14
+ */
15
+ export let routePrefix: string = "preview";
13
16
 
14
- function prismicPreviewEventHandler(event: Event) {
15
- event.preventDefault();
17
+ /**
18
+ * The name of the preview-specific route parameter prefixed during preview
19
+ * sessions.
20
+ *
21
+ * Only set this value if the route parameter's name differs from the
22
+ * parameter's value.
23
+ */
24
+ export let routePrefixName: string = routePrefix;
16
25
 
17
- invalidateAll();
18
- }
26
+ $: toolbarSrc = getToolbarSrc(repositoryName);
27
+
28
+ /**
29
+ * Set to `true` when the next `beforeNavigate()` call should not prefix the
30
+ * route.
31
+ */
32
+ let endingPreview = false;
19
33
 
34
+ // Register Prismic toolbar event handlers to refresh data on content updates.
20
35
  onMount(() => {
21
- window.addEventListener("prismicPreviewUpdate", prismicPreviewEventHandler);
22
- window.addEventListener("prismicPreviewEnd", prismicPreviewEventHandler);
36
+ const controller = new AbortController();
37
+
38
+ window.addEventListener(
39
+ "prismicPreviewUpdate",
40
+ (event) => {
41
+ event.preventDefault();
42
+ invalidateAll();
43
+ },
44
+ { signal: controller.signal },
45
+ );
46
+ window.addEventListener(
47
+ "prismicPreviewEnd",
48
+ (event) => {
49
+ event.preventDefault();
50
+
51
+ endingPreview = true;
52
+
53
+ goto(
54
+ new URL(
55
+ window.location.pathname.replace(
56
+ new RegExp(`^(\/${routePrefix}\/?$|\/${routePrefix}\/)`),
57
+ "/",
58
+ ),
59
+ window.location.origin,
60
+ ),
61
+ {
62
+ invalidateAll: true,
63
+ noScroll: true,
64
+ },
65
+ );
66
+ },
67
+ { signal: controller.signal },
68
+ );
23
69
 
24
70
  return () => {
25
- window.removeEventListener(
26
- "prismicPreviewUpdate",
27
- prismicPreviewEventHandler,
28
- );
29
- window.removeEventListener(
30
- "prismicPreviewEnd",
31
- prismicPreviewEventHandler,
32
- );
71
+ controller.abort();
33
72
  };
34
73
  });
74
+
75
+ beforeNavigate((navigation) => {
76
+ // Prefix links with the preview route parameter if the current
77
+ // route is in a preview session.
78
+ if (
79
+ navigation.to &&
80
+ navigation.from?.params?.[routePrefixName] === routePrefix &&
81
+ !(routePrefixName in (navigation.to.params || {}))
82
+ ) {
83
+ // If this callback is called due to a `prismicPreviewEnd`
84
+ // event, don't prefix the route. The exception is only
85
+ // valid for one call.
86
+ if (endingPreview) {
87
+ endingPreview = false;
88
+ return;
89
+ }
90
+
91
+ navigation.cancel();
92
+ goto(
93
+ new URL(
94
+ routePrefix + navigation.to.url.pathname,
95
+ navigation.to.url.origin,
96
+ ),
97
+ );
98
+ }
99
+ });
35
100
  </script>
36
101
 
37
102
  <svelte:head>
@@ -1,4 +1,5 @@
1
1
  import * as prismic from "@prismicio/client";
2
+ import { Cookies } from "@sveltejs/kit";
2
3
 
3
4
  export type RedirectToPreviewURLConfig = {
4
5
  /**
@@ -16,11 +17,23 @@ export type RedirectToPreviewURLConfig = {
16
17
  */
17
18
  request: Request;
18
19
 
20
+ /**
21
+ * The `cookies` object from a `+server` file.
22
+ *
23
+ * @see SvelteKit `+server` docs: \<https://kit.svelte.dev/docs/routing#server\>
24
+ */
25
+ cookies: Cookies;
26
+
19
27
  /**
20
28
  * The default redirect URL if a URL cannot be determined for the previewed
21
29
  * document.
22
30
  */
23
31
  defaultURL?: string;
32
+
33
+ /**
34
+ * The route parameter prefixed during preview sessions.
35
+ */
36
+ routePrefix?: string;
24
37
  };
25
38
 
26
39
  /**
@@ -49,6 +62,7 @@ export const redirectToPreviewURL = async (
49
62
  new URL(config.request.url).searchParams.get("token") ?? undefined;
50
63
  const documentID =
51
64
  new URL(config.request.url).searchParams.get("documentId") ?? undefined;
65
+ const routePrefix = config.routePrefix ?? "preview";
52
66
 
53
67
  const previewURL = await config.client.resolvePreviewURL({
54
68
  previewToken,
@@ -56,10 +70,19 @@ export const redirectToPreviewURL = async (
56
70
  defaultURL: config.defaultURL || "/",
57
71
  });
58
72
 
73
+ // Prevent a flash of non-preview content by setting the preview token
74
+ // on the initial page load.
75
+ if (previewToken) {
76
+ config.cookies.set(prismic.cookie.preview, previewToken, {
77
+ path: "/",
78
+ httpOnly: false,
79
+ });
80
+ }
81
+
59
82
  return new Response(undefined, {
60
83
  status: 307,
61
84
  headers: {
62
- Location: previewURL,
85
+ Location: "/" + routePrefix + previewURL,
63
86
  },
64
87
  });
65
88
  };