search-results-page.ts
1 import type { SearchResultsPage } from '@jet-app/app-store/api/models'; 2 import type { SeoData } from '@amp/web-app-components/src/components/MetaTags/types'; 3 import type I18N from '@amp/web-apps-localization'; 4 import { 5 isSearchResultShelf, 6 isRenderableInSearchResultsShelf, 7 } from '~/components/jet/shelf/SearchResultShelf.svelte'; 8 import { commaSeparatedList } from '../string-formatting'; 9 10 export function seoDataForSearchResultsPage( 11 page: SearchResultsPage, 12 i18n: I18N, 13 language: string, 14 ): SeoData { 15 const term = page?.searchTermContext?.term; 16 const pageTitle = i18n.t('ASE.Web.AppStore.Meta.TitleWithSiteName', { 17 title: page?.searchTermContext?.term, 18 }); 19 const shareTitle = i18n.t('ASE.Web.AppStore.Meta.TitleWithSiteName', { 20 title: i18n.t('ASE.Web.AppStore.Meta.SearchResults.Title', { 21 term: page?.searchTermContext?.term, 22 }), 23 }); 24 25 const resultsShelf = page?.shelves?.find(isSearchResultShelf) ?? null; 26 27 const renderableItems = (resultsShelf?.items ?? []).filter( 28 isRenderableInSearchResultsShelf, 29 ); 30 31 const appNames = renderableItems 32 .slice(0, 3) 33 .map((item) => item.lockup.title); 34 35 let description; 36 if (appNames.length) { 37 description = i18n.t( 38 'ASE.Web.AppStore.Meta.SearchResults.Description', 39 { 40 term, 41 listOfApps: commaSeparatedList(appNames, language), 42 }, 43 ); 44 } 45 46 return term 47 ? { 48 pageTitle, 49 socialTitle: shareTitle, 50 appleTitle: shareTitle, 51 description, 52 socialDescription: description, 53 appleDescription: description, 54 } 55 : {}; 56 }