+ {:else}
+
+ {/if}
+{/if}
+
+
diff --git a/src/components/Markdown/stores.ts b/src/components/Markdown/stores.ts
new file mode 100644
index 00000000..5705ac9d
--- /dev/null
+++ b/src/components/Markdown/stores.ts
@@ -0,0 +1,25 @@
+import { writable } from 'svelte/store';
+
+/**
+ * Set to `false` in the browser to ensure Markdown content correctly updates
+ * when a SvelteKit app hyrates.
+ *
+ * @example
+ * ```javascript
+ * // +layout.js
+ * import { staticMarkdown } from '@reuters-graphics/graphics-components';
+ * import { building } from '$app/environment';
+ *
+ * export const load = async() => {
+ * // Set the store with the value of building.
+ * staticMarkdown.set(building);
+ *
+ * // Markdown using this content will correctly refresh when
+ * // a reader loads your page.
+ * const content = await fetchPageContent();
+ *
+ * return { content };
+ * }
+ * ```
+ */
+export const staticMarkdown = writable(true);
diff --git a/src/components/Markdown/stories/docs/component.md b/src/components/Markdown/stories/docs/component.md
new file mode 100644
index 00000000..5ba4ae0a
--- /dev/null
+++ b/src/components/Markdown/stories/docs/component.md
@@ -0,0 +1,39 @@
+The Markdown component renders markdown into HTML. That's it!
+
+---
+
+```svelte
+
+
+
+```
+
+... well, almost.
+
+Owing to a weird quirk of Svelte's [`@html`](https://svelte.dev/docs/special-tags#html) directive (see [this issue](https://github.com/reuters-graphics/graphics-components/issues/148)), if you want your resulting HTML to be dynamic — e.g., update after a SvelteKit app [hydrates](https://kit.svelte.dev/docs/glossary#hydration) — then you may need to set the included `$staticMarkdown` store to `false` in the browser.
+
+For example, if you're refreshing some data with markdown strings in a SvelteKit project using a [load function](https://kit.svelte.dev/docs/load), set the store to reflect the [`building`](https://kit.svelte.dev/docs/modules#$app-environment-building) variable, which will correctly [prerender](https://kit.svelte.dev/docs/glossary#prerendering) your markdown content AND update it after fresh data is fetched in the browser.
+
+```javascript
+// +layout.js
+import { staticMarkdown } from '@reuters-graphics/graphics-components';
+import { building } from '$app/environment';
+
+/** @type {import('./$types').LayoutLoad} */
+export const load = async () => {
+ // Set the staticMarkdown store with the value of building.
+ staticMarkdown.set(building);
+
+ // Now this content will correctly refresh when a reader loads your page.
+ const resp = await fetch(
+ 'https://graphics.thomsonreuters.com/data/my-page-content.json'
+ );
+ const content = await resp.json();
+
+ return { content };
+};
+```
+
+If you're not updating your markdown content as above, you can safely leave the `$staticMarkdown` store alone and your page will do the right thing.
diff --git a/src/components/PhotoPack/PhotoPack.svelte b/src/components/PhotoPack/PhotoPack.svelte
index 88eee261..2a425f66 100644
--- a/src/components/PhotoPack/PhotoPack.svelte
+++ b/src/components/PhotoPack/PhotoPack.svelte
@@ -57,7 +57,7 @@
import Block from '../Block/Block.svelte';
import PaddingReset from '../PaddingReset/PaddingReset.svelte';
- import { marked } from 'marked';
+ import Markdown from '../Markdown/Markdown.svelte';
let containerWidth;
@@ -123,7 +123,7 @@
{#each row as img, i}
{#if img.caption}
- {@html marked(img.caption)}
+
{/if}
{/each}
diff --git a/src/components/Scroller/Embedded/Foreground.svelte b/src/components/Scroller/Embedded/Foreground.svelte
index a13bdaf8..c3247be1 100644
--- a/src/components/Scroller/Embedded/Foreground.svelte
+++ b/src/components/Scroller/Embedded/Foreground.svelte
@@ -4,8 +4,8 @@
export let step: ScrollerStep;
export let index: number;
- import { marked } from 'marked';
import Block from '../../Block/Block.svelte';
+ import Markdown from '../../Markdown/Markdown.svelte';
{#if step.foreground === '' || !step.foreground}
@@ -14,18 +14,18 @@
{#if typeof step.altText === 'string'}
- {@html marked.parse(step.altText)}
+
{/if}
{:else if typeof step.foreground === 'string'}
- {@html marked.parse(step.foreground)}
+
{#if typeof step.altText === 'string'}
- {@html marked.parse(step.altText)}
+
{/if}
diff --git a/src/components/Scroller/Foreground.svelte b/src/components/Scroller/Foreground.svelte
index fbaf5f41..bdae6c74 100644
--- a/src/components/Scroller/Foreground.svelte
+++ b/src/components/Scroller/Foreground.svelte
@@ -3,7 +3,7 @@
export let steps: ScrollerStep[] = [];
- import { marked } from 'marked';
+ import Markdown from '../Markdown/Markdown.svelte';
{#each steps as step, i}
@@ -16,13 +16,13 @@
{#if typeof step.altText === 'string'}
{/if}
{/if}
diff --git a/src/components/SimpleTimeline/SimpleTimeline.svelte b/src/components/SimpleTimeline/SimpleTimeline.svelte
index 4ecacefd..3c913044 100644
--- a/src/components/SimpleTimeline/SimpleTimeline.svelte
+++ b/src/components/SimpleTimeline/SimpleTimeline.svelte
@@ -39,7 +39,7 @@
import Block from '../Block/Block.svelte';
import Fa from 'svelte-fa/src/fa.svelte';
import { faLink } from '@fortawesome/free-solid-svg-icons';
- import { marked } from 'marked';
+ import Markdown from '../Markdown/Markdown.svelte';
@@ -76,7 +76,7 @@
{/if}
{#if event.context}
- {@html marked(event.context)}
+
{/if}
{/each}
diff --git a/src/index.js b/src/index.js
index 88c7d5e1..9a4d8135 100644
--- a/src/index.js
+++ b/src/index.js
@@ -24,11 +24,13 @@ export { default as HeroHeadline } from './components/HeroHeadline/Hero.svelte';
export { default as EndNotes } from './components/EndNotes/EndNotes.svelte';
export { default as InfoBox } from './components/InfoBox/InfoBox.svelte';
export { default as InlineAd } from './components/AdSlot/InlineAd.svelte';
+export { default as Markdown } from './components/Markdown/Markdown.svelte';
export { default as PaddingReset } from './components/PaddingReset/PaddingReset.svelte';
export { default as PhotoCarousel } from './components/PhotoCarousel/PhotoCarousel.svelte';
export { default as PhotoPack } from './components/PhotoPack/PhotoPack.svelte';
export { default as PymChild } from './components/PymChild/PymChild.svelte';
export { pymChildStore } from './components/PymChild/stores.js';
+export { staticMarkdown } from './components/Markdown/stores.js';
export { default as ReferralBlock } from './components/ReferralBlock/ReferralBlock.svelte';
export { default as ReutersGraphicsLogo } from './components/ReutersGraphicsLogo/ReutersGraphicsLogo.svelte';
export { default as ReutersLogo } from './components/ReutersLogo/ReutersLogo.svelte';