@@ -2,14 +2,14 @@ import type {Maybe} from './storefront-api-types.js';
22import type { WithContext , Thing } from 'schema-dts' ;
33import 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
162161export 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+
566566function 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