Merge pull request #229 from reuters-graphics/mf-seo

Updates SEO
This commit is contained in:
MinamiFunakoshiTR 2025-03-12 11:25:49 -05:00 committed by GitHub
commit bf2bcaed1f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 116 additions and 143 deletions

View file

@ -33,7 +33,7 @@ Venison shoulder *ham hock ham leberkas*. Flank beef ribs fatback, jerky meatbal
With the Graphics Kit, you'll likely get your text value from an ArchieML doc... With the Graphics Kit, you'll likely get your text value from an ArchieML doc...
```yaml ```yaml
# Archie ML doc # ArchieML doc
[blocks] [blocks]
type: text type: text

View file

@ -0,0 +1,80 @@
import { Meta, Canvas } from '@storybook/blocks';
import * as SEOStories from './SEO.stories.svelte';
<Meta of={SEOStories} />
# SEO
The `SEO` component adds essential metadata to pages.
```svelte
<script>
import { SEO } from '@reuters-graphics/graphics-components';
</script>
<SEO
baseUrl="https://www.reuters.com/graphics/world-coronavirus-tracker-and-maps"
pageUrl={new URL(
'https://www.reuters.com/graphics/world-coronavirus-tracker-and-maps/countries/united-kingdom/'
)}
seoTitle="A title for Google"
seoDescription="A description for Google"
shareTitle="A title for Twitter/Facebook"
shareDescription="A description for Twitter/Facebook"
shareImgPath="https://www.reuters.com/graphics/world-coronavirus-tracker-and-maps/assets/images/share.jpg"
shareImgAlt="An image showing global COVID infection rates"
publishTime="2020-09-15T00:00:00.000Z"
updateTime="2021-01-10T12:30:00.000Z"
authors={[
{ name: 'Jane Doe', link: 'https://www.reuters.com/authors/jane-doe/' },
{ name: 'John Doe', link: 'https://www.reuters.com/authors/john-doe/' },
]}
/>
```
## Using with ArchieML docs
With the Graphics Kit, you'll likely get many of your text values from an ArchieML doc...
```yaml
# ArchieML doc
slug: ROOT-SLUG/WILD
seoTitle: Page title for search
seoDescription: Page description for search
shareTitle: Page title for social media
shareDescription: Page description for social media
shareImgPath: images/reuters-graphics.jpg
shareImgAlt: Alt text for share image.
```
... which you'll pass to the `SEO` component.
```svelte
<script>
import { SEO } from '@reuters-graphics/graphics-components';
import pkg from '$pkg';
import content from '$locales/en/content.json';
import { assets } from '$app/paths';
import { page } from '$app/stores';
</script>
<SEO
baseUrl={VITE_BASE_URL}
pageUrl={$page.url}
seoTitle={content.seoTitle}
seoDescription={content.seoDescription}
shareTitle={content.shareTitle}
shareDescription={content.shareDescription}
shareImgPath={`${assets}/${content.shareImgPath}`}
shareImgAlt={content.shareImgAlt}
publishTime={pkg?.reuters?.graphic?.published}
updateTime={pkg?.reuters?.graphic?.updated}
authors={pkg?.reuters?.graphic?.authors}
/>
```
> **Note:** For _reasons_, we can't document the value of `VITE_BASE_URL` below. It's `import` + `.meta.env.BASE_URL` (concatenate all that) in the Graphics Kit and other Vite-based rigs.
<Canvas of={SEOStories.Demo} />
```

View file

@ -1,49 +1,23 @@
<script module lang="ts"> <script module lang="ts">
// @ts-ignore raw import { defineMeta } from '@storybook/addon-svelte-csf';
import componentDocs from './stories/docs/component.md?raw';
// @ts-ignore raw
import archieMLDocs from './stories/docs/archieML.md?raw';
import SEO from './SEO.svelte'; import SEO from './SEO.svelte';
import { const { Story } = defineMeta({
withComponentDocs,
withStoryDocs,
} from '$lib/docs/utils/withParams.js';
export const meta = {
title: 'Components/Ads & analytics/SEO', title: 'Components/Ads & analytics/SEO',
component: SEO, component: SEO,
...withComponentDocs(componentDocs), });
};
</script> </script>
<script> <div>View page source to see the SEO metadata.</div>
import { Template, Story } from '@storybook/addon-svelte-csf';
</script>
<Template >
{#snippet children({ args })}
<SEO {...args} />
<div>Nothing to see here. 😎</div>
{/snippet}
</Template>
<Story <Story
name="Default" name="Demo"
args="{{ args={{
baseUrl: 'https://graphics.reuters.com', baseUrl: 'https://www.reuters.com',
pageUrl: new URL('https://graphics.reuters.com/hello-world/'), seoTitle: 'A title for Google',
publishTime: new Date('2020-09-15').toISOString(), seoDescription: 'A description for Google',
}}" shareTitle: 'A title for Twitter/Facebook',
/> shareDescription: 'A description for Twitter/Facebook',
shareImgPath:
<Story 'https://www.reuters.com/graphics/world-coronavirus-tracker-and-maps/assets/images/share.jpg',
name="ArchieML" }}
args="{{
baseUrl: 'https://graphics.reuters.com',
pageUrl: new URL('https://graphics.reuters.com/hello-world/'),
publishTime: new Date('2020-09-15').toISOString(),
}}"
{...withStoryDocs(archieMLDocs)}
/> />

View file

@ -2,77 +2,59 @@
<script lang="ts"> <script lang="ts">
interface GraphicAuthor { interface GraphicAuthor {
name: string; name: string;
url: string; link: string;
} }
interface Props { interface Props {
/** /**
* Base url for the page, which in [Vite-based projects](https://vitejs.dev/guide/build.html#public-base-path) * Base url for the page, which in [Vite-based projects](https://vitejs.dev/guide/build.html#public-base-path) is globally available as `import.meta.env.BASE_URL`.
* is globally available as `import.meta.env.BASE_URL`.
* @requiredx
* @type {string}
*/ */
baseUrl?: string; baseUrl: string;
/** /**
* [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object for the page. * [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object for the page.
* @required
* @type {URL}
*/ */
pageUrl?: URL | null; pageUrl: URL;
/** /**
* SEO title * SEO title
* @required
* @type {string}
*/ */
seoTitle: string; seoTitle: string;
/** /**
* SEO description * SEO description
* @required
* @type {string}
*/ */
seoDescription: string; seoDescription: string;
/** /**
* Share title * Share title
* @required
* @type {string}
*/ */
shareTitle: string; shareTitle: string;
/** /**
* Share description * Share description
* @required
* @type {string}
*/ */
shareDescription: string; shareDescription: string;
/** /**
* Share image path. **Must be an absolute path.** * Share image path. **Must be an absolute path.**
* @required
* @type {string}
*/ */
shareImgPath: string; shareImgPath: string;
/** /**
* Share image alt text, up to 420 characters. * Share image alt text, up to 420 characters.
* @type {string}
*/ */
shareImgAlt?: string; shareImgAlt?: string;
/** /**
* Publish time as an [ISO string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) * Publish time as an [ISO string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
* @type {string}
*/ */
publishTime?: string; publishTime?: string;
/** /**
* Updated time as an [ISO string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) * Updated time as an [ISO string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
* @type {string}
*/ */
updateTime?: string; updateTime?: string;
/** /**
* Array of authors for the piece. Each author object must have `name` and `url` attributes. * Array of authors for the piece. Each author object must have `name` and `link` attributes.
*/ */
authors?: GraphicAuthor[]; authors?: GraphicAuthor[];
} }
let { let {
baseUrl = '', baseUrl,
pageUrl = null, pageUrl,
seoTitle, seoTitle,
seoDescription, seoDescription,
shareTitle, shareTitle,
@ -83,7 +65,6 @@
updateTime = '', updateTime = '',
authors = [], authors = [],
}: Props = $props(); }: Props = $props();
const getOrigin = (baseUrl: string) => { const getOrigin = (baseUrl: string) => {
try { try {
return new URL(baseUrl).origin; return new URL(baseUrl).origin;
@ -97,7 +78,7 @@
let origin = $derived(getOrigin(baseUrl)); let origin = $derived(getOrigin(baseUrl));
let canonicalUrl = $derived( let canonicalUrl = $derived(
(origin + pageUrl?.pathname).replace(/index\.html\/$/, '') (origin + (pageUrl?.pathname || '')).replace(/index\.html\/$/, '')
); );
const orgLdJson = { const orgLdJson = {
@ -138,10 +119,10 @@
dateCreated: publishTime, dateCreated: publishTime,
datePublished: publishTime, datePublished: publishTime,
dateModified: updateTime, dateModified: updateTime,
author: authors.map(({ name, url }) => ({ author: authors.map(({ name, link }) => ({
'@type': 'Person', '@type': 'Person',
name, name,
url, url: link,
})), })),
creator: authors.map(({ name }) => name), creator: authors.map(({ name }) => name),
articleSection: 'Graphics', articleSection: 'Graphics',
@ -153,8 +134,8 @@
<svelte:head> <svelte:head>
{#key canonicalUrl} {#key canonicalUrl}
<title>{seoTitle}</title> <title>{seoTitle}</title>
<meta name="description" content="{seoDescription}" /> <meta name="description" content={seoDescription} />
<link rel="canonical" href="{canonicalUrl}" /> <link rel="canonical" href={canonicalUrl} />
<link <link
rel="shortcut icon" rel="shortcut icon"
type="image/x-icon" type="image/x-icon"
@ -179,26 +160,26 @@
sizes="96x96" sizes="96x96"
/> />
<meta property="og:url" content="{canonicalUrl}" /> <meta property="og:url" content={canonicalUrl} />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:title" content="{shareTitle}" itemprop="name" /> <meta property="og:title" content={shareTitle} itemprop="name" />
<meta <meta
property="og:description" property="og:description"
content="{shareDescription}" content={shareDescription}
itemprop="description" itemprop="description"
/> />
<meta property="og:image" content="{shareImgPath}" itemprop="image" /> <meta property="og:image" content={shareImgPath} itemprop="image" />
<meta property="og:site_name" content="Reuters" /> <meta property="og:site_name" content="Reuters" />
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@ReutersGraphics" /> <meta name="twitter:site" content="@ReutersGraphics" />
<meta name="twitter:creator" content="@ReutersGraphics" /> <meta name="twitter:creator" content="@ReutersGraphics" />
<meta name="twitter:domain" content="{origin}" /> <meta name="twitter:domain" content={origin} />
<meta name="twitter:title" content="{shareTitle}" /> <meta name="twitter:title" content={shareTitle} />
<meta name="twitter:description" content="{shareDescription}" /> <meta name="twitter:description" content={shareDescription} />
<meta name="twitter:image" content="{shareImgPath}" /> <meta name="twitter:image" content={shareImgPath} />
{#if shareImgAlt} {#if shareImgAlt}
<meta name="twitter:image:alt" content="{shareImgAlt}" /> <meta name="twitter:image:alt" content={shareImgAlt} />
{/if} {/if}
<meta property="fb:app_id" content="319194411438328" /> <meta property="fb:app_id" content="319194411438328" />

View file

@ -1,36 +0,0 @@
```yaml
slug: ROOT-SLUG/WILD
seoTitle: Page title for search
seoDescription: Page description for search
shareTitle: Page title for social media
shareDescription: Page description for social media
shareImgPath: images/reuters-graphics.jpg
shareImgAlt: Alt text for share image.
```
```svelte
<script>
import { SEO } from '@reuters-graphics/graphics-components';
import pkg from '$pkg';
import content from '$locales/en/content.json';
import { assets } from '$app/paths';
import { page } from '$app/stores';
</script>
<SEO
baseUrl="{VITE_BASE_URL}"
pageUrl="{$page.url}"
seoTitle="{content.seoTitle}"
seoDescription="{content.seoDescription}"
shareTitle="{content.shareTitle}"
shareDescription="{content.shareDescription}"
shareImgPath="{`${assets}/${content.shareImgPath}`}"
shareImgAlt="{content.shareImgAlt}"
publishTime="{pkg?.reuters?.graphic?.published}"
updateTime="{pkg?.reuters?.graphic?.updated}"
authors="{pkg?.reuters?.graphic?.authors}"
/>
```
> **Note:** For _reasons_, we can't document the value of `VITE_BASE_URL` below. It's `import` + `.meta.env.BASE_URL` (concatenate all that) in the Graphics Kit and other Vite-based rigs.

View file

@ -1,26 +0,0 @@
The `SEO` component adds essential metadata to published pages.
```svelte
<script>
import { SEO } from '@reuters-graphics/graphics-components';
</script>
<SEO
baseUrl="https://graphics.reuters.com"
pageUrl="{new URL(
'https://graphics.reuters.com/world-coronavirus-tracker-and-maps/'
)}"
seoTitle="A title for Google"
seoDescription="A description for Google"
shareTitle="A title for Twitter/Facebook"
shareDecription="A description for Twitter/Facebook"
shareImgPath="https://graphics.reuters.com/world-coronavirus-tracker-and-maps/assets/images/share.jpg"
shareImgAlt="An image showing global COVID infection rates"
publishTime="2020-09-15T00:00:00.000Z"
updateTime="2021-01-10T12:30:00.000Z"
authors="{[
{ name: 'Jane Doe', url: 'https://twitter.com/JaneDoe' },
{ name: 'John Doe', url: 'https://twitter.com/JohnDoe' },
]}"
/>
```