Skip to content
This repository was archived by the owner on Mar 3, 2023. It is now read-only.

Commit ce65016

Browse files
committed
most ts errors fixed
1 parent ba5f405 commit ce65016

File tree

2 files changed

+37
-95
lines changed

2 files changed

+37
-95
lines changed

packages/react/src/seo.test.ts

Lines changed: 7 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {expect, describe, it} from 'vitest';
22
import {generateSeoTags} from './seo.js';
3+
import type {Product} from 'schema-dts';
34

45
describe('generateSeoTags', () => {
56
it('removes undefined values', () => {
@@ -434,7 +435,7 @@ describe('generateSeoTags', () => {
434435
{
435436
"key": "meta-https://example.com/image-1.jpg-og:image:height",
436437
"props": {
437-
"content": "100",
438+
"content": 100,
438439
"property": "og:image:height",
439440
},
440441
"tag": "meta",
@@ -515,7 +516,7 @@ describe('generateSeoTags', () => {
515516
{
516517
"key": "meta-https://example.com/image-1.jpg-og:image:height",
517518
"props": {
518-
"content": "100",
519+
"content": 100,
519520
"property": "og:image:height",
520521
},
521522
"tag": "meta",
@@ -563,7 +564,7 @@ describe('generateSeoTags', () => {
563564
{
564565
"key": "meta-https://example.com/image-2.jpg-og:image:width",
565566
"props": {
566-
"content": "100",
567+
"content": 100,
567568
"property": "og:image:width",
568569
},
569570
"tag": "meta",
@@ -690,7 +691,7 @@ describe('generateSeoTags', () => {
690691
{
691692
"key": "meta-https://example.com/image-1.swf-og:video:height",
692693
"props": {
693-
"content": "100",
694+
"content": 100,
694695
"property": "og:video:height",
695696
},
696697
"tag": "meta",
@@ -799,63 +800,6 @@ describe('generateSeoTags', () => {
799800
});
800801

801802
describe('jsonLd', () => {
802-
it('should infer default values from the URL', () => {
803-
// Given
804-
const input = {
805-
jsonLd: {},
806-
url: 'https://hydrogen.shopify.com/products/1234',
807-
};
808-
809-
// When
810-
const output = generateSeoTags(input);
811-
812-
// Then
813-
expect(output).toMatchInlineSnapshot(`
814-
[
815-
{
816-
"key": "link-canonical",
817-
"props": {
818-
"href": "https://hydrogen.shopify.com/products/1234",
819-
"rel": "canonical",
820-
},
821-
"tag": "link",
822-
},
823-
{
824-
"key": "meta-og:type",
825-
"props": {
826-
"content": "website",
827-
"property": "og:type",
828-
},
829-
"tag": "meta",
830-
},
831-
{
832-
"key": "meta-og:url",
833-
"props": {
834-
"content": "https://hydrogen.shopify.com/products/1234",
835-
"property": "og:url",
836-
},
837-
"tag": "meta",
838-
},
839-
{
840-
"key": "meta-twitter:card",
841-
"props": {
842-
"content": "summary_large_image",
843-
"name": "twitter:card",
844-
},
845-
"tag": "meta",
846-
},
847-
{
848-
"children": "{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Product\\",\\"url\\":\\"https://hydrogen.shopify.com/products/1234\\"}",
849-
"key": "script-application/ld+json",
850-
"props": {
851-
"type": "application/ld+json",
852-
},
853-
"tag": "script",
854-
},
855-
]
856-
`);
857-
});
858-
859803
it('should add additional jsonLd values', () => {
860804
// Given
861805
const input = {
@@ -879,11 +823,11 @@ describe('generateSeoTags', () => {
879823
},
880824
],
881825
},
882-
},
826+
} satisfies Product,
883827
};
884828

885829
// When
886-
const output = generateSeoTags(input);
830+
const output = generateSeoTags<Product>(input);
887831

888832
// Then
889833
expect(output).toMatchInlineSnapshot(`

packages/react/src/seo.ts

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import type {Maybe} from './storefront-api-types.js';
22
import type {WithContext, Thing} from 'schema-dts';
33
import type {ComponentPropsWithoutRef} from 'react';
44

5-
export interface Seo {
5+
export interface Seo<Schema extends Thing = Thing> {
66
/**
77
* The <title> HTML element defines the document's title that is shown in a browser's title bar or a page's tab. It
88
* only contains text; tags within the element are ignored.
99
*
1010
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title
1111
*/
12-
title: Maybe<string> | undefined;
12+
title?: Maybe<string>;
1313
/**
1414
* Generate the title from a template that includes a `%s` placeholder for the title.
1515
*
@@ -21,7 +21,7 @@ export interface Seo {
2121
* }
2222
* ```
2323
*/
24-
titleTemplate: Maybe<string> | undefined | null;
24+
titleTemplate?: Maybe<string> | null;
2525
/**
2626
* The media associated with the given page (images, videos, etc). If you pass a string, it will be used as the
2727
* `og:image` meta tag. If you pass an object or an array of objects, that will be used to generate
@@ -45,26 +45,25 @@ export interface Seo {
4545
* ```
4646
*
4747
*/
48-
media:
48+
media?:
4949
| Maybe<string>
5050
| Partial<SeoMedia>
51-
| (Partial<SeoMedia> | Maybe<string>)[]
52-
| undefined;
51+
| (Partial<SeoMedia> | Maybe<string>)[];
5352
/**
5453
* The description of the page. This is used in the `name="description"` meta tag as well as the `og:description` meta
5554
* tag.
5655
*
5756
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
5857
*/
59-
description: Maybe<string> | undefined;
58+
description?: Maybe<string>;
6059
/**
6160
* The canonical URL of the page. This is used to tell search engines which URL is the canonical version of a page.
6261
* This is useful when you have multiple URLs that point to the same page. The value here will be used in the
6362
* `rel="canonical"` link tag as well as the `og:url` meta tag.
6463
*
6564
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
6665
*/
67-
url: Maybe<string> | undefined;
66+
url?: Maybe<string>;
6867
/**
6968
* The handle is used to generate the `twitter:site` and `twitter:creator` meta tags. Include the `@` symbol in the
7069
* handle.
@@ -76,7 +75,7 @@ export interface Seo {
7675
* }
7776
* ```
7877
*/
79-
handle: Maybe<string> | undefined;
78+
handle?: Maybe<string>;
8079
/**
8180
* The `jsonLd` property is used to generate the `application/ld+json` script tag. This is used to provide structured
8281
* data to search engines. The value should be an object that conforms to the schema.org spec. The `type` property
@@ -131,7 +130,7 @@ export interface Seo {
131130
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script
132131
*
133132
*/
134-
jsonLd?: <T extends SchemaType>(type: T) => WithContext<T>;
133+
jsonLd?: WithContext<Schema>;
135134
/**
136135
* The `alternates` property is used to specify the language and geographical targeting when you have multiple
137136
* versions of the same page in different languages. The `url` property tells search engines about these variations
@@ -156,7 +155,7 @@ export interface Seo {
156155
*
157156
* @see https://support.google.com/webmasters/answer/189077?hl=en
158157
*/
159-
alternates: LanguageAlternate | LanguageAlternate[] | undefined;
158+
alternates?: LanguageAlternate | LanguageAlternate[];
160159
}
161160

162161
export interface LanguageAlternate {
@@ -191,31 +190,20 @@ export interface CustomHeadTagObject {
191190
key: string;
192191
}
193192

194-
export type SchemaType =
195-
| 'Product'
196-
| 'ItemList'
197-
| 'Organization'
198-
| 'WebSite'
199-
| 'WebPage'
200-
| 'BlogPosting'
201-
| 'Thing';
202-
203-
function ensureArray<T>(value: T | T[]): T[] {
204-
return Array.isArray(value) ? value : [value];
205-
}
206-
207193
/**
208194
* The `generateSeoTags` function generates the SEO title, meta, link and script (JSON Linking Data) tags for a page. It
209195
* pairs well with the SEO component in `@shopify/hydrogen` when building a Hydrogen Remix app, but can be used on its
210196
* own if you want to generate the tags yourself.
211197
*/
212-
export function generateSeoTags<T extends Seo = Seo>(
213-
seoInput: Partial<T>
214-
): CustomHeadTagObject[] {
198+
export function generateSeoTags<
199+
Schema extends Thing,
200+
T extends Seo<Schema> = Seo<Schema>
201+
>(seoInput: T): CustomHeadTagObject[] {
215202
const output: CustomHeadTagObject[] = [];
216203

217204
// https://github.com/google/schema-dts/issues/98
218-
let jsonLd: WithContext<Exclude<Thing, string>> = {
205+
// @ts-expect-error - Exclude string from Schema
206+
let jsonLd: WithContext<Exclude<Schema, string>> = {
219207
'@context': 'https://schema.org',
220208
'@type': 'Thing',
221209
};
@@ -298,9 +286,8 @@ export function generateSeoTags<T extends Seo = Seo>(
298286
break;
299287

300288
case 'jsonLd':
301-
content = value as Record<string, unknown>;
289+
jsonLd = {...jsonLd, ...value};
302290

303-
jsonLd = {...jsonLd, ...content};
304291
break;
305292

306293
case 'media': {
@@ -563,6 +550,19 @@ function inferMimeType(url: Maybe<string> | undefined) {
563550
return 'image/jpeg';
564551
}
565552

553+
function ensureArray<T>(value: T | T[]): T[] {
554+
return Array.isArray(value) ? value : [value];
555+
}
556+
557+
export type SchemaType =
558+
| 'Product'
559+
| 'ItemList'
560+
| 'Organization'
561+
| 'WebSite'
562+
| 'WebPage'
563+
| 'BlogPosting'
564+
| 'Thing';
565+
566566
function inferSchemaType(url: Maybe<string> | undefined): SchemaType {
567567
const defaultType = 'Thing';
568568

@@ -575,7 +575,6 @@ function inferSchemaType(url: Maybe<string> | undefined): SchemaType {
575575
type: 'WebSite',
576576
pattern: '^/$',
577577
},
578-
579578
{
580579
type: 'Product',
581580
pattern: '/products/.*',
@@ -612,7 +611,6 @@ function inferSchemaType(url: Maybe<string> | undefined): SchemaType {
612611

613612
const typeMatches = routes.filter((route) => {
614613
const {pattern} = route;
615-
616614
const regex = new RegExp(pattern);
617615
return regex.test(url);
618616
});

0 commit comments

Comments
 (0)