diff --git a/package.json b/package.json index cc3d92ff..91dab76a 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@storybook/theming": "6.5.9", "@sveltejs/vite-plugin-svelte": "^1.0.1", "@tsconfig/svelte": "^3.0.0", + "@types/gtag.js": "^0.0.12", "@types/proper-url-join": "^2.1.1", "@types/react-syntax-highlighter": "^15.5.4", "@typescript-eslint/eslint-plugin": "^5.33.1", @@ -237,4 +238,4 @@ ".": "./dist/index.js" }, "svelte": "./dist/index.js" -} \ No newline at end of file +} diff --git a/src/components/Analytics/Analytics.stories.svelte b/src/components/Analytics/Analytics.stories.svelte new file mode 100644 index 00000000..c3263416 --- /dev/null +++ b/src/components/Analytics/Analytics.stories.svelte @@ -0,0 +1,45 @@ + + + + + + + + + + +
Nothing to see here
+
+ + + +
Nothing to see here
+
diff --git a/src/components/Analytics/Analytics.svelte b/src/components/Analytics/Analytics.svelte new file mode 100644 index 00000000..3d8512f0 --- /dev/null +++ b/src/components/Analytics/Analytics.svelte @@ -0,0 +1,29 @@ + + + + diff --git a/src/components/Analytics/providers/chartbeat.ts b/src/components/Analytics/providers/chartbeat.ts new file mode 100644 index 00000000..6fd791c6 --- /dev/null +++ b/src/components/Analytics/providers/chartbeat.ts @@ -0,0 +1,46 @@ +// Reuters Chartbeat UID +const UID = 52639; + +/* eslint-disable */ +const attachScript = () => { + // If script is already attached, skip + if ( + document.querySelector( + 'script[src="//static.chartbeat.com/js/chartbeat.js"]' + ) + ) { return; } + // ... else attach it. + const e = document.createElement('script'); + const n = document.getElementsByTagName('script')[0]; + e.type = 'text/javascript'; + e.async = true; + e.src = '//static.chartbeat.com/js/chartbeat.js'; + n.parentNode.insertBefore(e, n); +}; +/* eslint-enable */ + +export default (authors: { name: string }[]) => { + // @ts-ignore + const config = window._sf_async_config = (window._sf_async_config || {}); + config.uid = UID; + config.domain = 'reuters.com'; + config.flickerControl = false; + config.useCanonical = true; + config.useCanonicalDomain = true; + config.sections = 'Graphics'; + config.authors = authors.map((a) => a.name).join(','); + + try { + attachScript(); + } catch (e) { console.warn(`Error initialising Chartbeat Analytics: ${e}`); } +}; + +export const registerPageview = () => { + // @ts-ignore + if (!window.pSUPERFLY) return; + // @ts-ignore + window.pSUPERFLY({ + path: window.location.pathname, + title: document.title, + }); +}; diff --git a/src/components/Analytics/providers/ga.ts b/src/components/Analytics/providers/ga.ts new file mode 100644 index 00000000..c4674f89 --- /dev/null +++ b/src/components/Analytics/providers/ga.ts @@ -0,0 +1,45 @@ +// Reuters Google Tag ID +const GOOGLE_TAG_ID = 'G-W3Q2X6NTNM'; + +/* eslint-disable */ +const attachScript = () => { + // If script is already attached, skip + if ( + document.querySelector( + `script[src="https://www.googletagmanager.com/gtag/js?id=${GOOGLE_TAG_ID}"]` + ) + ) + return; + // ... else attach it. + const e = document.createElement('script'); + const n = document.getElementsByTagName('script')[0]; + e.type = 'text/javascript'; + e.async = true; + e.src = `https://www.googletagmanager.com/gtag/js?id=${GOOGLE_TAG_ID}`; + n.parentNode.insertBefore(e, n); +}; +/* eslint-enable */ + +export default () => { + try { + // @ts-ignore + window.dataLayer = window.dataLayer || []; + if (!window.gtag) { + attachScript(); + /** @type {Gtag.Gtag} */ + window.gtag = (...args) => { + // @ts-ignore + window.dataLayer.push(...args); + }; + window.gtag('js', new Date()); + window.gtag('config', GOOGLE_TAG_ID); + } + } catch (e) { console.warn(`Error initialising Google Analytics: ${e}`); } +}; + +export const registerPageview = () => { + if (!window.gtag) return; + window.gtag('event', 'page_view', { + page_location: window.location.origin + window.location.pathname, + }); +}; diff --git a/src/components/Analytics/providers/index.ts b/src/components/Analytics/providers/index.ts new file mode 100644 index 00000000..9b2fdba9 --- /dev/null +++ b/src/components/Analytics/providers/index.ts @@ -0,0 +1,2 @@ +export { default as ga } from './ga'; +export { default as chartbeat } from './chartbeat'; diff --git a/src/components/Analytics/stories/docs/component.md b/src/components/Analytics/stories/docs/component.md new file mode 100644 index 00000000..1ddd7b8e --- /dev/null +++ b/src/components/Analytics/stories/docs/component.md @@ -0,0 +1,11 @@ +Add Google and Chartbeat analytics to your page. + +```svelte + + + +``` diff --git a/src/components/Analytics/stories/docs/environments.md b/src/components/Analytics/stories/docs/environments.md new file mode 100644 index 00000000..74089219 --- /dev/null +++ b/src/components/Analytics/stories/docs/environments.md @@ -0,0 +1,17 @@ +Generally, you only want to send page analytics in production environments. + +In a SvelteKit context, you can use `$app` stores to restrict when you send analytics. + +For example, the following excludes analytics from pages in development or hosted on our preview server: + +```svelte + + +{#if !dev && $page.url?.hostname !== 'graphics.thomsonreuters.com'} + +{/if} +``` diff --git a/src/components/Analytics/stories/docs/multipage.md b/src/components/Analytics/stories/docs/multipage.md new file mode 100644 index 00000000..b8336dda --- /dev/null +++ b/src/components/Analytics/stories/docs/multipage.md @@ -0,0 +1,32 @@ +If you're using analytics to measure a multipage newsapp that uses [client-side routing](https://kit.svelte.dev/docs/glossary#routing), then you may need to trigger analytics after virtual page navigation. + +This component also exports a function you can call to register pageviews. + +For example, here's how you can use SvelteKit's [`afterNavigate`](https://kit.svelte.dev/docs/modules#$app-navigation-afternavigate) lifecycle to capture additional pageviews: + +```svelte + + + +``` diff --git a/src/components/SEO/SEO.svelte b/src/components/SEO/SEO.svelte index 9c9e49a5..4b4a0720 100644 --- a/src/components/SEO/SEO.svelte +++ b/src/components/SEO/SEO.svelte @@ -1,15 +1,9 @@